基于Python +Selenium的爬蟲詳解

一.背景


1. Selenium

Selenium 是一個用于web應(yīng)用程序自動化測試的工具们镜,直接運(yùn)行在瀏覽器當(dāng)中瑰步,支持chrome的妖、firefox等主流瀏覽器绣檬。可以通過代碼控制與頁面上元素進(jìn)行交互(點(diǎn)擊嫂粟、輸入等)娇未,也可以獲取指定元素的內(nèi)容。


2.優(yōu)劣

劣勢:

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


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


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




優(yōu)勢:

1兼贸、不需要做復(fù)雜的抓包段直、構(gòu)造請求、解析數(shù)據(jù)等寝受,開發(fā)難度相對要低一些。


2罕偎、其訪問參數(shù)跟使用瀏覽器的正常用戶一模一樣很澄,訪問行為也相對更像正常用戶,不容易被反爬蟲策略命中颜及。


3甩苛、生成的瀏覽器環(huán)境可以自動運(yùn)行 JS 文件,所以不用擔(dān)心如何逆向混淆過的JS文件生成用作人機(jī)校驗(yàn)的參數(shù)俏站,如馬蜂窩酒店評論的人機(jī)校驗(yàn)參數(shù)_sn讯蒲,網(wǎng)易云音樂評論的人機(jī)校驗(yàn)參數(shù)params、encSecKey肄扎∧郑可以自行抓包查看赁酝。


4、如果需要抓取同一個前端頁面上面來自不同后端接口的信息旭等,如OTA酒店詳情頁的酒店基礎(chǔ)信息酌呆、價格、評論等搔耕,使用Selenium可以在一次請求中同時完成對三個接口的調(diào)用隙袁,相對方便。


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

1.環(huán)境

python3.6 + Macos


2.依賴包

Selenium


安裝的時候是大寫的 S 菩收,import的時候是 小寫 s。


pip install Selenium


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

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


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


選擇合適的版本下載解壓后放在隨便一個位置即可腊凶。


4.hello world

from selenium import webdriver


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

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)行上述代碼划咐,會打開一個瀏覽器,并且加載去哪兒的酒店列表頁'''


這時候可以通過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)

#返回 展示在列表頁的酒店信息

#同理褐缠,可以find_element_by_[class_name|name] 等,均可完成查詢风瘦。




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




#當(dāng)需要查詢的唯一標(biāo)識帶有空格時万搔,可以使用find_elements_by_css_selector胡桨,否則會報錯。

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é)約時間酗捌,這樣屬于調(diào)整本地設(shè)置呢诬,在傳參上并不會有異常。


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ū)動路徑

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)入酒店詳情頁




2.模擬鍵盤輸入

hotel_search = driver.find_element_by_id("jxQ")

hotel_search.send_keys("如")

hotel_search.send_keys("如家")

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


3.模擬下拉

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


from selenium.webdriver.common.action_chains import? ActionChains


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

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)懸停、雙擊澳迫、按住左鍵等等局齿,此處不展開介紹。


四橄登、一個完整的模擬瀏覽器爬蟲


from selenium import webdriver

from selenium.webdriver.common.action_chains import? ActionChains

import time


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

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

driver = webdriver.Chrome(executable_path=path)


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

driver.get(url)?



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


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

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) #等待頁面加載完再進(jìn)行后續(xù)操作


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

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

windows = driver.window_handles


#此處可以爬整個頁面任何想要想要的元素

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]) #切換到剛打開的酒店詳情頁

? ? hotel_info_clawer()

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

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


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



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

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


以自如的房租為例:

from selenium import webdriver


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

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)#由于自如的價格用圖片做了替換充坑,這樣并不能獲取到實(shí)際價格减江,需要獲取圖片再做ocr處理


"對指定元素部分截圖再保存"

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




安裝ocr工具:

Tesseract是一個開源的OCR引擎,能識別100多種語言(中捻爷,英辈灼,韓,日也榄,德巡莹,法…等等),但是Tesseract對手寫的識別能力較差甜紫,僅適用于打印字體降宅。


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

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

brew install tesseract


使用Tesseract:


tesseract ~/price.png result

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


在python下使用Tesseract:


首先安裝依賴包: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期開課啦】

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

偷偷告訴你前50名额嘿,還可獲得價值300元的京東購物卡呦~


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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末岩睁,一起剝皮案震驚了整個濱河市钞脂,隨后出現(xiàn)的幾起案子揣云,更是在濱河造成了極大的恐慌,老刑警劉巖冰啃,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件邓夕,死亡現(xiàn)場離奇詭異刘莹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)焚刚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進(jìn)店門点弯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人矿咕,你說我怎么就攤上這事抢肛。” “怎么了碳柱?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵捡絮,是天一觀的道長。 經(jīng)常有香客問我莲镣,道長福稳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任瑞侮,我火速辦了婚禮的圆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘半火。我一直安慰自己越妈,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布慈缔。 她就那樣靜靜地躺著叮称,像睡著了一般。 火紅的嫁衣襯著肌膚如雪藐鹤。 梳的紋絲不亂的頭發(fā)上瓤檐,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天,我揣著相機(jī)與錄音娱节,去河邊找鬼挠蛉。 笑死,一個胖子當(dāng)著我的面吹牛肄满,可吹牛的內(nèi)容都是我干的谴古。 我是一名探鬼主播,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼稠歉,長吁一口氣:“原來是場噩夢啊……” “哼掰担!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起怒炸,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤带饱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體勺疼,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡教寂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了执庐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锻离。...
    茶點(diǎn)故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡网严,死狀恐怖晚岭,靈堂內(nèi)的尸體忽然破棺而出州袒,到底是詐尸還是另有隱情,我是刑警寧澤递鹉,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布婚被,位于F島的核電站,受9級特大地震影響梳虽,放射性物質(zhì)發(fā)生泄漏址芯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一窜觉、第九天 我趴在偏房一處隱蔽的房頂上張望谷炸。 院中可真熱鬧,春花似錦禀挫、人聲如沸旬陡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽描孟。三九已至,卻和暖如春砰左,著一層夾襖步出監(jiān)牢的瞬間匿醒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工缠导, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留廉羔,地道東北人。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓僻造,卻偏偏與公主長得像憋他,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子髓削,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容