昨天之所以水了诊霹,是因為日更30天了羞延,歇一歇,同時也是為了完成今天的這個爬蟲脾还,畢竟第一次使用selenium+chrome爬取網(wǎng)站伴箩。
前兩天寫分析ajax爬蟲,是分析了網(wǎng)站請求的參數(shù)鄙漏、請求地址嗤谚、上傳的表單,模擬瀏覽器訪問頁面來的到源碼泥张,但是有時候ajax的參數(shù)非常多呵恢,而且經(jīng)過加密,很難找到規(guī)律媚创。這時候我們就需要使用selenium這個強大的庫了渗钉,它可以控制瀏覽器,模擬人的操作,直接獲取瀏覽器渲染完成后的頁面源碼鳄橘,真正做到可見即可爬声离。
不多說,讓我們開始吧瘫怜!
selenium需要我們配合瀏覽器使用术徊,它支持很多款瀏覽器,但是我更喜歡chrome鲸湃,因為它調(diào)試起來更方便赠涮,就像很多前段程序猿也喜歡chrome一樣,反正我不喜歡IE暗挑,讓它當(dāng)場去世吧笋除!
chromeDriver 也是必需品。下載下來后放在環(huán)境的script文件下炸裆。
這次也是垃它,還是剩下一小部分沒完成,現(xiàn)在還沒學(xué)習(xí)到烹看。之后會完善国拇。
- 搜索商品后會直接跳到登錄界面,所以我直接打開的登錄界面惯殊,現(xiàn)在我只能掃碼登陸酱吝,賬號密碼登陸會出滑動驗證碼,這在ChromeDriver里無法完成靠胜,我就直接等10s讓我掃碼登陸了掉瞳。
其實吧我感覺爬蟲沒什么好講的,主要是對抗反爬機制能夠給我?guī)砜鞓防四_@次淘寶的反爬很厲害陕习。換頁的速度不能太快,太快的話址愿,到18頁就會被要求進行滑動驗證该镣,但是由于瀏覽器問題,總是失敗响谓。所以我在換頁之前用了10s的延時才能全部爬下來损合。
一共爬了100頁,我輸入的‘ipad’娘纷,一共4404條數(shù)據(jù)嫁审,全部存在數(shù)據(jù)庫中,方便以后使用:
[圖片上傳失敗...(image-e5e97b-1553952994597)]
這次的程序中設(shè)計等待時間的概念赖晶,一個是隱式等待律适,一個是顯示等待辐烂。
隱式等待就是等待給定的時間,在尋找頁面中的元素捂贿,如果時間到了還沒加載出來纠修,就報錯,這一般用的少厂僧,但這次我也用了扣草,在掃碼登錄的時候。
顯示等待是指如果再規(guī)定的時間內(nèi)加載出來了颜屠,就獲取節(jié)點辰妙,如果沒有加載出來報錯。
代碼不長汽纤,具體內(nèi)容就不講了上岗,沒意思。你爬蟲遇到問題了蕴坪,來對比下,找找不同敬锐,這樣才能得到最大的進步背传,什么都直接說出來,就沒有找答案的這個過程台夺,也就沒有任何的成就感径玖,而且我寫這個,只是我為了記錄自己的學(xué)習(xí)過程颤介。最終雖然得到了我想要的梳星,但反爬機制沒解決,感覺得到之后一切都變得索然無味滚朵。
還有就是瀏覽器滑動驗證這一點冤灾,這將是我接下來的學(xué)習(xí)方向,之后就可以為所欲為了辕近。
import re
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from pyquery import PyQuery as pq
from config import *
import pymongo
# chrome_options = webdriver.ChromeOptions()
# chrome_options.add_argument()
browser = webdriver.Chrome()
wait = WebDriverWait(browser, 10)
client = pymongo.MongoClient(MONGODB_HOST, MONGODB_POST)
db = client[MONGODB_DB]
collection = db[MONGODB_COLLECTION]
def login():
print("正在登錄")
# 需要用手機淘寶掃二維碼登錄才能搜索
browser.get(url='https://login.taobao.com')
# 10s用來掃碼登錄
browser.implicitly_wait(10)
def search():
print("正在查找",KEYWORD)
try:
input = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, "#q"))
)
submit = wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "#J_TSearchForm > div.search-button > button"))
)
input.send_keys(KEYWORD)
submit.click()
total = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,
"#mainsrp-pager > div > div > div > div.total")))
get_goods()
return total.text
except TimeoutError:
return search()
def next_page(page_number):
print("正在換頁", page_number)
try:
input = wait.until(
EC.presence_of_element_located((By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.form > input"))
)
submit = wait.until(
EC.element_to_be_clickable(
(By.CSS_SELECTOR, "#mainsrp-pager > div > div > div > div.form > span.btn.J_Submit"))
)
input.clear()
input.send_keys(page_number)
submit.click()
wait.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR,
'#mainsrp-pager > div > '\
'div > div > ul > '\
'li.item.active > '\
'span'), str(page_number)))
get_goods()
except Exception:
next_page(page_number)
def get_goods():
try:
wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,
'#mainsrp-itemlist .items '
'.item')))
html = browser.page_source
doc = pq(html)
items = doc('#mainsrp-itemlist .items .item').items()
for item in items:
goods = {
'img': item.find('.pic .img').attr('data-src'),
'price': item.find('.price').text(),
'deal': item.find('.deal-cnt').text(),
'title': item.find('.title').text(),
'shop': item.find('.shop').text(),
'location': item.find('.location').text()
}
save_to_mongodb(goods)
except Exception:
print("獲取商品失敗")
def save_to_mongodb(result):
try:
if db[MONGODB_COLLECTION].insert_one(result):
print("存儲到數(shù)據(jù)成功", result)
except Exception:
print("存儲到數(shù)據(jù)庫失敗", result)
def main():
login()
total = search()
total = int(re.compile('(\d+)').search(total).group(0))
for i in range(2, total + 1):
if i % 15 == 0:
time.sleep(20)
next_page(i)
if __name__ == '__main__':
main()
在使用前一定要記得把該裝的庫都裝了韵吨,數(shù)據(jù)庫打開,網(wǎng)絡(luò)通暢移宅。
得抓緊學(xué)習(xí)了归粉,要趕在工大春招之前學(xué)完。
之前在百度貼吧幫別人解決問題漏峰,這讓我很開心糠悼,忘記了時間。所以今天晚了點浅乔。