基于Python +Selenium的爬蟲(chóng)詳解

一.背景


1. Selenium

Selenium 是一個(gè)用于web應(yīng)用程序自動(dòng)化測(cè)試的工具,直接運(yùn)行在瀏覽器當(dāng)中,支持chrome、firefox等主流瀏覽器??梢酝ㄟ^(guò)代碼控制與頁(yè)面上元素進(jìn)行交互(點(diǎn)擊、輸入等),也可以獲取指定元素的內(nèi)容。


2.優(yōu)劣

劣勢(shì):

相比于抓包→構(gòu)造請(qǐng)求→解析返回值的爬蟲(chóng),由于Selenium需要生成一個(gè)瀏覽器環(huán)境,所有操作(與元素交互、獲取元素內(nèi)容等)均需要等待頁(yè)面加載完畢后才可以繼續(xù)進(jìn)行,所以速度相比構(gòu)造請(qǐng)求的慢很多。


對(duì)于為了反爬做了特殊處理的展示內(nèi)容,如字體加密(參考貓眼)、圖片替換數(shù)字(參考自如)等,可能取不到想要的數(shù)據(jù)。


使用圖片替換數(shù)字的自如:




優(yōu)勢(shì):

1、不需要做復(fù)雜的抓包、構(gòu)造請(qǐng)求、解析數(shù)據(jù)等,開(kāi)發(fā)難度相對(duì)要低一些。


2、其訪問(wèn)參數(shù)跟使用瀏覽器的正常用戶(hù)一模一樣,訪問(wèn)行為也相對(duì)更像正常用戶(hù),不容易被反爬蟲(chóng)策略命中。


3、生成的瀏覽器環(huán)境可以自動(dòng)運(yùn)行 JS 文件,所以不用擔(dān)心如何逆向混淆過(guò)的JS文件生成用作人機(jī)校驗(yàn)的參數(shù),如馬蜂窩酒店評(píng)論的人機(jī)校驗(yàn)參數(shù)_sn,網(wǎng)易云音樂(lè)評(píng)論的人機(jī)校驗(yàn)參數(shù)params、encSecKey。可以自行抓包查看。


4、如果需要抓取同一個(gè)前端頁(yè)面上面來(lái)自不同后端接口的信息,如OTA酒店詳情頁(yè)的酒店基礎(chǔ)信息、價(jià)格、評(píng)論等,使用Selenium可以在一次請(qǐng)求中同時(shí)完成對(duì)三個(gè)接口的調(diào)用,相對(duì)方便。


二、實(shí)現(xiàn)

1.環(huán)境

python3.6 + Macos


2.依賴(lài)包

Selenium


安裝的時(shí)候是大寫(xiě)的 S ,import的時(shí)候是 小寫(xiě) s。


pip install Selenium


3.瀏覽器驅(qū)動(dòng)(webdriver)

加載瀏覽器環(huán)境需要下載對(duì)應(yīng)的瀏覽器驅(qū)動(dòng),此處選擇 Chrome。


下載地址:http://npm.taobao.org/mirrors/chromedriver/ ,


選擇合適的版本下載解壓后放在隨便一個(gè)位置即可。


4.hello world

from selenium import webdriver


'''這里填剛剛下載的驅(qū)動(dòng)的路徑'''

path = '/Applications/Google Chrome.app/Contents/chromedriver'


driver = webdriver.Chrome(executable_path=path)


url = 'http://hotel.qunar.com/city/beijing_city/'

driver.get(url)


'''運(yùn)行上述代碼,會(huì)打開(kāi)一個(gè)瀏覽器,并且加載去哪兒的酒店列表頁(yè)'''


這時(shí)候可以通過(guò)webdriver自帶的一些的一些方法獲取元素內(nèi)容或者與元素進(jìn)行交互。


image-20190108224445170

image-20190108224445170


#返回ID = js_block_beijing_city_7810的元素信息

hotel_info = driver.find_element_by_id('js_block_beijing_city_7810')

print(hotel_info.text)

#返回 展示在列表頁(yè)的酒店信息

#同理,可以find_element_by_[class_name|name] 等,均可完成查詢(xún)。




也可以通過(guò)方法 find_elements查找符合某條件的一組元素,以列表的形式返回。




#當(dāng)需要查詢(xún)的唯一標(biāo)識(shí)帶有空格時(shí),可以使用find_elements_by_css_selector,否則會(huì)報(bào)錯(cuò)。

hotel_list = driver.find_elements_by_css_selector("[class='b_result_box js_list_block? b_result_commentbox']")

print(hotel_list)

#返回酒店列表的全部信息。




5.關(guān)閉圖片加載

在不需要抓取圖片的情況下,可以設(shè)置不加載圖片,節(jié)約時(shí)間,這樣屬于調(diào)整本地設(shè)置,在傳參上并不會(huì)有異常。


from selenium import webdriver


chrome_opt = webdriver.ChromeOptions()

prefs={"profile.managed_default_content_settings.images":2}

chrome_opt.add_experimental_option("prefs",prefs)


path = '' #驅(qū)動(dòng)路徑

browser_noPic = webdriver.Chrome(executable_path=path,chrome_options=chrome_opt)


三、使用webdriver與元素進(jìn)行交互

1.模擬鼠標(biāo)點(diǎn)擊



hotel_info = driver.find_element_by_id("js_plugin_tag_beijing_city_7810")

hotel.info.click()

#進(jìn)入酒店詳情頁(yè)




2.模擬鍵盤(pán)輸入

hotel_search = driver.find_element_by_id("jxQ")

hotel_search.send_keys("如")

hotel_search.send_keys("如家")

#由于搜索框輸入的第一個(gè)字會(huì)被選中,所以需要第二次才能完整輸入,當(dāng)然也可以模擬按鍵盤(pán)的 →(右鍵)取消選中后再次輸入。


3.模擬下拉

webdriver中對(duì)鼠標(biāo)的操作的方法封裝在ActionChains類(lèi)中 ,使用前要先導(dǎo)入ActionChains類(lèi):


from selenium.webdriver.common.action_chains import? ActionChains


"""在頁(yè)面頂部、底部個(gè)找了一個(gè)元素,并模擬鼠標(biāo)從頂?shù)降椎幕瑒?dòng)"""

start = driver.find_element_by_class_name('e_above_header')

target = driver.find_element_by_class_name('qn_footer')

ActionChains(driver).drag_and_drop(start,target).perform()


此外,webdiver還提供豐富的交互功能,比如鼠標(biāo)懸停、雙擊、按住左鍵等等,此處不展開(kāi)介紹。


四、一個(gè)完整的模擬瀏覽器爬蟲(chóng)


from selenium import webdriver

from selenium.webdriver.common.action_chains import? ActionChains

import time


'''這里填剛剛下載的驅(qū)動(dòng)的路徑'''

path = '/Users/./Desktop/chromedriver'

driver = webdriver.Chrome(executable_path=path)


url = 'http://hotel.qunar.com/city/beijing_city/'

driver.get(url)?



time.sleep(6) #等待頁(yè)面加載完再進(jìn)行后續(xù)操作


"""在頁(yè)面頂部、底部個(gè)找了一個(gè)元素,并模擬鼠標(biāo)從頂?shù)降椎幕瑒?dòng)"""

start = driver.find_element_by_class_name('e_above_header')

target = driver.find_element_by_class_name('qn_footer')

ActionChains(driver).drag_and_drop(start,target).perform()


time.sleep(5) #等待頁(yè)面加載完再進(jìn)行后續(xù)操作


hotel_link_list = driver.find_elements_by_css_selector("[class='item_price js_hasprice']")

print("在此頁(yè)面共有酒店",len(hotel_link_list),"家")

windows = driver.window_handles


#此處可以爬整個(gè)頁(yè)面任何想要想要的元素

list_hotel_info=[]

def hotel_info_clawer():

? ? list_hotel_info.append([driver.find_element_by_class_name("info").text,

? ? ? ? ? ? ? ? ? ? ? ? ? ? driver.find_element_by_class_name("js-room-table").text,

? ? ? ? ? ? ? ? ? ? ? ? ? ? driver.find_element_by_class_name("dt-module").text])



for i in range(len(hotel_link_list)):

? ? hotel_link_list[i].click()

? ? driver.switch_to.window(windows[-1]) #切換到剛打開(kāi)的酒店詳情頁(yè)

? ? hotel_info_clawer()

? ? driver.close() #關(guān)閉已經(jīng)爬完的酒店詳情頁(yè)? ??

? ? print("已經(jīng)抓取酒店",i,"家")


#后面可以補(bǔ)充翻頁(yè)繼續(xù)抓取的部分



五、使用截圖+OCR抓取關(guān)鍵數(shù)據(jù)

對(duì)于做了特殊處理的信息,如上述的貓眼電影的票房信息、自如的價(jià)格等,不適用于直接獲取制定元素的信息進(jìn)行抓取,可以使用截圖+OCR的方式抓取此類(lèi)數(shù)據(jù)。


以自如的房租為例:

from selenium import webdriver


'''這里填剛剛下載的驅(qū)動(dòng)的路徑'''

path = '/Applications/Google Chrome.app/Contents/chromedriver'

driver = webdriver.Chrome(executable_path=path)


url = 'http://www.ziroom.com/z/vr/61715463.html'

driver.get(url)


price = diver.find_element_by_class_name('room_price')


print(price.text)#由于自如的價(jià)格用圖片做了替換,這樣并不能獲取到實(shí)際價(jià)格,需要獲取圖片再做ocr處理


"對(duì)指定元素部分截圖再保存"

price.screenshot('/Users/./Desktop/price.png')




安裝ocr工具:

Tesseract是一個(gè)開(kāi)源的OCR引擎,能識(shí)別100多種語(yǔ)言(中,英,韓,日,德,法…等等),但是Tesseract對(duì)手寫(xiě)的識(shí)別能力較差,僅適用于打印字體。


//僅安裝tesseract,不安裝訓(xùn)練工具和其他語(yǔ)音包,需要識(shí)別中文的話(huà)得額外下載

//下載地址:https://github.com/tesseract-ocr/tessdata

brew install tesseract


使用Tesseract:


tesseract ~/price.png result

//識(shí)別圖片并將結(jié)果存在result里面


在python下使用Tesseract:


首先安裝依賴(lài)包:pip install pytesseract


import pytesseract

from PIL import Image


# open image

image = Image.open('price.png')

code = pytesseract.image_to_string(image)

print(code)


今日福利

【Java11期開(kāi)課啦】

8大實(shí)戰(zhàn)案例模塊,歷時(shí)三年沉淀,Java4.0震撼發(fā)布!

偷偷告訴你前50名,還可獲得價(jià)值300元的京東購(gòu)物卡呦~


如有疑問(wèn),請(qǐng)留言告知,或者咨詢(xún)檸檬班軟件測(cè)試培訓(xùn)機(jī)構(gòu):www.lemonban.com官網(wǎng)客服哦

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容