自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

python爬蟲(chóng)入門(mén)基本知識(shí)

開(kāi)發(fā) 后端
我們?yōu)g覽網(wǎng)頁(yè)的瀏覽器和手機(jī)應(yīng)用客戶(hù)端與服務(wù)器通信幾乎都是基于HTTP協(xié)議,而爬蟲(chóng)可以看作是一個(gè)另類(lèi)的客戶(hù)端,它把自己偽裝成瀏覽器或者手機(jī)應(yīng)用客戶(hù)端,按照自己的邏輯貪婪的向服務(wù)器索取數(shù)據(jù),如何向服務(wù)器索取數(shù)據(jù),所以了解HTTP協(xié)議就顯得很有必要了。

基礎(chǔ)知識(shí)

HTTP協(xié)議

我們?yōu)g覽網(wǎng)頁(yè)的瀏覽器和手機(jī)應(yīng)用客戶(hù)端與服務(wù)器通信幾乎都是基于HTTP協(xié)議,而爬蟲(chóng)可以看作是一個(gè)另類(lèi)的客戶(hù)端,它把自己偽裝成瀏覽器或者手機(jī)應(yīng)用客戶(hù)端,按照自己的邏輯貪婪的向服務(wù)器索取數(shù)據(jù),如何向服務(wù)器索取數(shù)據(jù),所以了解HTTP協(xié)議就顯得很有必要了。

HTTP協(xié)議中文名稱(chēng)是超文本傳輸協(xié)議,是一個(gè)基于請(qǐng)求與響應(yīng)模式的、無(wú)狀態(tài)的、應(yīng)用層的協(xié)議,?;赥CP的連接方式。請(qǐng)求和響應(yīng)模式很好理解,客戶(hù)端發(fā)送請(qǐng)求,服務(wù)器響應(yīng)客戶(hù)端的請(qǐng)求,就像學(xué)校食堂打菜一樣,你和打菜阿姨說(shuō)要哪份菜,她才會(huì)給你盛哪份菜。

python爬蟲(chóng)入門(mén)基本知識(shí)

無(wú)狀態(tài)是指協(xié)議對(duì)于事務(wù)處理沒(méi)有記憶能力。缺少狀態(tài)意味著如果后續(xù)處理需要前面的信息,則它必須重傳,這樣可能導(dǎo)致每次連接傳送的數(shù)據(jù)量增大。另一方面,在服務(wù)器不需要先前信息時(shí)它的應(yīng)答就較快。形象點(diǎn)說(shuō),可以把服務(wù)器看成是沒(méi)有記憶的大學(xué)食堂打飯打菜,在每次請(qǐng)求中,阿姨并不知道你之前有沒(méi)有打過(guò)菜,也不知道你是不是合法的學(xué)生,所以你只能一邊舉著學(xué)生證一邊和阿姨說(shuō)我要這個(gè)菜,阿姨看到你的學(xué)生證后才會(huì)給你打菜,而這個(gè)學(xué)生證就是你每次需要重傳的數(shù)據(jù)信息。

當(dāng)我們?cè)跒g覽器地址欄中輸入http://www.bilibili.com 并敲入回車(chē)后,瀏覽器會(huì)構(gòu)造HTTP請(qǐng)求發(fā)送到服務(wù)器,在收到服務(wù)器的HTTP響應(yīng)后,瀏覽器會(huì)解析頁(yè)面,繼續(xù)向服務(wù)器請(qǐng)求圖片、視頻、js腳本等數(shù)據(jù),直到頁(yè)面加載完成,最終展示給我們的就是B站主頁(yè)了。這是我用Fiddler抓的包,展示的是HTTP最原生的面貌,接下來(lái)我就根據(jù)這張圖具體的講解HTTP協(xié)議,以及寫(xiě)爬蟲(chóng)需要關(guān)注的一些點(diǎn)。

python爬蟲(chóng)入門(mén)基本知識(shí)

HTTP請(qǐng)求由三部分組成,分別是: 請(qǐng)求行、消息報(bào)頭、請(qǐng)求正文。 在接收和解釋請(qǐng)求消息后,服務(wù)器返回一個(gè)HTTP響應(yīng)消息,HTTP響應(yīng)也是由三個(gè)部分組成,分別是:狀態(tài)行、消息報(bào)頭、響應(yīng)正文。

HTTP方法

HTTP請(qǐng)求的請(qǐng)求行以一個(gè)方法符號(hào)開(kāi)頭,以空格分開(kāi),后面跟著請(qǐng)求的URI和協(xié)議的版本。請(qǐng)求方法都是大寫(xiě),有很多種,常見(jiàn)的有GET POST DELETE PUT,各種方法之間的區(qū)別不大。

python爬蟲(chóng)入門(mén)基本知識(shí)

這里羅列了一些常用的方法,一般來(lái)講,GET表示向服務(wù)器請(qǐng)求URI對(duì)應(yīng)的資源,POST表示向服務(wù)器提交數(shù)據(jù),DELETE表示刪除數(shù)據(jù),PUT表示修改數(shù)據(jù)。但這都是一種約定,沒(méi)有強(qiáng)制的要求,如果你碰見(jiàn)用DELETE方法提交數(shù)據(jù)也沒(méi)必要大驚小怪。在實(shí)際寫(xiě)爬蟲(chóng)的過(guò)程中,我們只需要按照抓包請(qǐng)求構(gòu)造數(shù)據(jù)即可,沒(méi)有必要在意用了什么方法。

報(bào)頭字段

重點(diǎn)講解幾個(gè)寫(xiě)爬蟲(chóng)需要關(guān)注的字段

  • User-Agent 出現(xiàn)在請(qǐng)求報(bào)頭中,表示客戶(hù)端的操作系統(tǒng)、瀏覽器型號(hào)版本等信息。服務(wù)器可以根據(jù)此報(bào)頭向客戶(hù)端返回不同的頁(yè)面以適應(yīng)客戶(hù)端。有些網(wǎng)站(知乎)會(huì)校驗(yàn)此報(bào)頭,不填寫(xiě)或者不主流的報(bào)頭都不能拿到正常的頁(yè)面。因此自己在寫(xiě)爬蟲(chóng)的時(shí)候最好將從瀏覽器中拷貝到代碼中。
  • Cookie 出現(xiàn)在請(qǐng)求抱頭中,前面我們說(shuō)過(guò)HTTP是基于請(qǐng)求與響應(yīng)模式并且無(wú)狀態(tài)的協(xié)議,之前舉了打菜阿姨的例子,Cookie就相當(dāng)于每次請(qǐng)求中的學(xué)生證,它可以記錄用戶(hù)的身份信息。當(dāng)我們自己寫(xiě)爬蟲(chóng)的時(shí)候,如果需要登陸,并且登陸又有驗(yàn)證碼或者短信驗(yàn)證時(shí),最簡(jiǎn)單的方法就是從瀏覽器中把cookie拷貝到爬蟲(chóng)中,就可以騙過(guò)服務(wù)器了。
  • Set-Cookie 出現(xiàn)在響應(yīng)抱頭中,讓客戶(hù)端更新頁(yè)面關(guān)聯(lián)的Cookie,還是拿食堂阿姨的例子,如果你的響應(yīng)報(bào)頭有這個(gè)字段,意思就是阿姨重新給你了一個(gè)學(xué)生證,下次打飯你得用最新的學(xué)生證,原來(lái)的學(xué)生證不好使。如果你在模擬瀏覽器或者客戶(hù)端登陸,需要將此報(bào)頭更新已有的Cookie,不過(guò)Scrapy和requests都可以自動(dòng)更新,因此不需要你再手動(dòng)設(shè)置。
  • Content-Type 標(biāo)明請(qǐng)求正文或者響應(yīng)正文的格式,客戶(hù)端或者服務(wù)器會(huì)根據(jù)此字段選擇合適的方式解析正文內(nèi)容,以下是一些常見(jiàn)的值

python爬蟲(chóng)入門(mén)基本知識(shí)

  • Content-Length 標(biāo)明請(qǐng)求正文或者響應(yīng)正文的長(zhǎng)度,在使用requests構(gòu)造請(qǐng)求的時(shí)候,我們不需要顯式的加上此字段,requests會(huì)根據(jù)請(qǐng)求正文自動(dòng)計(jì)算添加。
  • Content-Encoding 在某些情況下,正文會(huì)講過(guò)壓縮后傳輸,此字段會(huì)指明壓縮的類(lèi)型(gzip和壓縮參數(shù))
  • Transfer-Encoding 如果正文內(nèi)容過(guò)長(zhǎng),HTTP協(xié)議允許將此字段設(shè)置為chunked,然后分塊傳輸響應(yīng)正文
  • Connection 在HTTP1.1之前的版本,不支持持久連接,所謂的持久鏈接意思就是:HTTP協(xié)議一般通過(guò)TCP協(xié)議實(shí)現(xiàn),客戶(hù)端和服務(wù)器經(jīng)過(guò)TCP三次握手建立連接,在請(qǐng)求和響應(yīng)結(jié)束之后,此連接繼續(xù)保持,當(dāng)之后還有請(qǐng)求的時(shí)候,就不需要重新通過(guò)三次握手再建立連接,這樣可以極大的降低客戶(hù)端和服務(wù)器的IO負(fù)載。

在自己寫(xiě)爬蟲(chóng)的時(shí)候,我們可以根據(jù)瀏覽器的抓包數(shù)據(jù)有選擇的添加一些請(qǐng)求報(bào)頭,其實(shí)大部分情況下都可以直接使用瀏覽器中的請(qǐng)求頭,為了避免不必要的麻煩,盡可能像的模仿瀏覽器總是沒(méi)有錯(cuò)的。

響應(yīng)碼

響應(yīng)消息的第一行的狀態(tài)行包括HTTP的協(xié)議版本、狀態(tài)碼、狀態(tài)碼含義。按照約定

  • 2xx表示請(qǐng)求成功
  • 3xx表示重定向
  • 4xx表示客戶(hù)端錯(cuò)誤(403 Forbiden 404 Not Found)
  • 5xx表示服務(wù)器錯(cuò)誤(502 網(wǎng)關(guān)錯(cuò)誤)

爬蟲(chóng)開(kāi)發(fā)

一般來(lái)說(shuō)開(kāi)發(fā)爬蟲(chóng)的過(guò)程是這樣的

  1. 抓包分析獲取數(shù)據(jù)的URL
  2. 通過(guò)python從上一步的URL獲取數(shù)據(jù)
  3. 從上一步獲取的HTML頁(yè)面或者JSON數(shù)據(jù)中解析出感興趣的數(shù)據(jù)
  4. 存儲(chǔ)數(shù)據(jù)

下面就講解這四個(gè)關(guān)鍵點(diǎn)

抓包發(fā)包工具

寫(xiě)爬蟲(chóng)的第一步就是分析想要的數(shù)據(jù)瀏覽器是通過(guò)什么URL拿到的,抓包也就在所難免。最好用的抓包工具當(dāng)然是谷歌瀏覽器了,右鍵檢查,選中網(wǎng)絡(luò),重新刷新頁(yè)面就可以看到加載此網(wǎng)頁(yè)所有的HTTP請(qǐng)求了,如果此鏈接有跳轉(zhuǎn)地址,跳轉(zhuǎn)之前的HTTP請(qǐng)求會(huì)被清掉,所以記得選上preserve log,尤其是登陸的時(shí)候,一般都會(huì)有跳轉(zhuǎn)。

python爬蟲(chóng)入門(mén)基本知識(shí)

再介紹另外兩個(gè)HTTP抓包工具——Fiddler和Charles,分別在windows和macos使用。它們可以為我們展示更多HTTP的細(xì)節(jié),將請(qǐng)求和響應(yīng)都調(diào)至Raw模式下,我們就可以一睹HTTP請(qǐng)求和響應(yīng)的真實(shí)面貌。

通過(guò)抓包分析出具體的URL后,想進(jìn)一步確認(rèn)自己構(gòu)造的參數(shù)和報(bào)頭能否正確獲取到數(shù)據(jù),應(yīng)該怎么做呢?不怕,postman可以幫你,你可以很輕松的選擇方法,定義header,添加各種類(lèi)型的body。

python爬蟲(chóng)入門(mén)基本知識(shí)

python請(qǐng)求數(shù)據(jù)

講完了基本的HTTP協(xié)議知識(shí)后,大家可能會(huì)疑問(wèn)那我該如何模仿瀏覽器或者手機(jī)客戶(hù)端去向服務(wù)器發(fā)送HTTP請(qǐng)求呢?python的原生庫(kù)urllib、第三方庫(kù)requests、pycurl等都支持HTTP協(xié)議,既然有這么多工具可以用,大家可能就又有疑問(wèn)該選擇哪個(gè)工具了。在此我特地安利大家用一下requests,它讓爬蟲(chóng)變得如此簡(jiǎn)單,讓你再也不用為字符編碼、重定向、cookie、響應(yīng)解壓縮煩惱了。如果你堅(jiān)持用原生的庫(kù),那么有以下問(wèn)題需要你一一解決,這些都是當(dāng)年自己趟過(guò)的坑,絕非危言聳聽(tīng)。

  1. 需要自己判斷服務(wù)器返回?cái)?shù)據(jù)的編碼格式,如果這個(gè)地方你不能正確判斷,那恭喜你之后的每一步,你都必須面對(duì)亂碼的問(wèn)題
  2. 重定向,urllib不能自動(dòng)判斷重定向,需要自己解析重定向的鏈接并重新請(qǐng)求
  3. 如果模擬登陸,你必須要手動(dòng)保證Cookie正確更新和發(fā)送
  4. 很多情況下響應(yīng)正文是壓縮過(guò)的,需要做解壓處理
  5. 對(duì)于比較長(zhǎng)的響應(yīng)正文,服務(wù)器會(huì)將正文分段傳輸,所以還需要你做拼接操作
  6. 原生的urllib對(duì)HTTPS和持久連接都支持不好

當(dāng)你花了一整天,寫(xiě)了好幾百行的代碼終于解決上面的問(wèn)題后,而你旁邊的同事可能早已經(jīng)把數(shù)據(jù)下載完并愉快的約妹子去了。所以用requests吧,兄弟們用了都說(shuō)好。下面我用兩個(gè)例子講解一下如何用requests獲取想要的數(shù)據(jù),并教你如何解決這些問(wèn)題:

  • 如何發(fā)送不同方法的請(qǐng)求
  • 如何保存cookie
  • 如何添加代理
  • 如何處理編碼問(wèn)題

B站

假如我想下載B站里面某位小姐姐所有上傳的視頻,應(yīng)該怎么辦呢?首先你需要找到這位小姐姐的視頻主頁(yè)

python爬蟲(chóng)入門(mén)基本知識(shí)

但是通過(guò)谷歌瀏覽器右鍵查看頁(yè)面源碼,沒(méi)有從html中找到這些視頻的播放信息,唯一的可能就是視頻數(shù)據(jù)是通過(guò)js腳本調(diào)用服務(wù)器獲取,然后生成的這張頁(yè)面。爬蟲(chóng)小白可能會(huì)疑問(wèn),難道我需要像瀏覽器一樣分析js腳本,然后模擬js執(zhí)行嗎?其實(shí)不用這么復(fù)雜,只需要簡(jiǎn)單的分析抓包結(jié)構(gòu),就可以找到請(qǐng)求URL了。

python爬蟲(chóng)入門(mén)基本知識(shí)

獲取視頻的URL: http://space.bilibili.com/ajax/member/getSubmitVideos?mid=79415852&pagesize=30&tid=0&page=1&keyword=&order=senddate

那么問(wèn)題又來(lái)了,這個(gè)URL的其他參數(shù)是干啥的呢?憑經(jīng)驗(yàn),mid肯定是這位小姐姐的用戶(hù)id,page和pagesize是負(fù)責(zé)分頁(yè)用的,keyword和是用來(lái)搜索的關(guān)鍵字,order是排序選項(xiàng),剩下的tid是干啥的呢?其實(shí)寫(xiě)爬蟲(chóng)很多時(shí)候都會(huì)遇到這種問(wèn)題,不知道某個(gè)參數(shù)的含義,也不確定正確的取值范圍,需要一些嘗試和運(yùn)氣,這里我們不管它就好。而返回的字段中有一個(gè)aid,那肯定是視頻的id,有這個(gè)就可以自己拼接出播放鏈接了。

python爬蟲(chóng)入門(mén)基本知識(shí)

是不是很簡(jiǎn)單,通過(guò)response.ok查看請(qǐng)求是否正確返回,因?yàn)榇私涌诘臄?shù)據(jù)為json格式,直接通過(guò)response.json()就可以直接拿到格式化的數(shù)據(jù)。

知乎

雖然現(xiàn)在知乎對(duì)未登錄用戶(hù)展示的內(nèi)容越來(lái)越多,但是仍會(huì)有一些限制,用爬蟲(chóng)模擬登陸可以之后再去爬取數(shù)據(jù),可以避免很多不必要的麻煩,現(xiàn)在就講一講如何用requests模擬用戶(hù)登陸。

還是和之前一樣,在登陸頁(yè)面打開(kāi)谷歌瀏覽器的抓包窗口,輸入用戶(hù)名和密碼點(diǎn)擊確定,然后在茫茫請(qǐng)求中找到發(fā)送登陸信息的那個(gè)HTTP請(qǐng)求即可,功夫不負(fù)有心人,我們終于找到了登陸的請(qǐng)求。

python爬蟲(chóng)入門(mén)基本知識(shí)

等等,請(qǐng)求里面還有一個(gè)_xsrf,這是一個(gè)什么鬼參數(shù),其實(shí)呢這是一個(gè)防止跨站請(qǐng)求偽造而生成的一個(gè)隨機(jī)數(shù),可以通過(guò)解析https://www.zhihu.com/#signin 頁(yè)面獲取,這一部分我在下面會(huì)講解如何HTML獲取數(shù)據(jù),現(xiàn)在假設(shè)我們已經(jīng)拿到這個(gè)數(shù)據(jù)了,如何將用戶(hù)名和密碼登陸呢?

python爬蟲(chóng)入門(mén)基本知識(shí)

如果我們想要自動(dòng)保存Cookie信息,只需要生成一個(gè)Session對(duì)象,之后所有的請(qǐng)求通過(guò)此對(duì)象完成,requests會(huì)像瀏覽器一樣自動(dòng)更新cookie信息,并在每次請(qǐng)求的時(shí)候加上cookie,因此在成功的發(fā)送post登陸請(qǐng)求之后,就可以用session在保持登陸狀態(tài)請(qǐng)求數(shù)據(jù)了。需要注意的是在請(qǐng)求的時(shí)候我特意去掉了Cookie和Content-Length報(bào)頭,因?yàn)閞equests會(huì)自動(dòng)加上,所以不需要我們特意關(guān)注。

更多關(guān)于requests的使用可以查看官方文檔:

英文: http://docs.python-requests.org/en/master/

中文: http://cn.python-requests.org/zh_CN/latest/user/quickstart.html

python解析數(shù)據(jù)

因?yàn)閭€(gè)人在解析數(shù)據(jù)的時(shí)候遇到過(guò)很多編碼的坑,所以在繼續(xù)講解之前告訴大家一些如何避免編碼問(wèn)題的方法。python2中有兩種字符串:unicode和str,它們分別對(duì)應(yīng)python3中的str和bytes。如何定義這兩種類(lèi)型的變量在下圖中給大家列出來(lái)了。

python爬蟲(chóng)入門(mén)基本知識(shí)

以python3為例講解這兩種類(lèi)型的區(qū)別。python3中的str每一個(gè)字符可以存儲(chǔ)一個(gè)英文字母、一個(gè)漢字甚至一個(gè)emoji表情,它可以通過(guò)特定的編碼方式,例如utf-8或者gbk生成bytes,在不同的編碼格式下,可能需要2-3個(gè)字符常能表示一個(gè)漢字。bytes可以指定解碼格式解碼生成str,如果指定的解碼格式不匹配,就會(huì)導(dǎo)致亂碼問(wèn)題。為了避免亂碼問(wèn)題,最好的方式就是使用str,等到需要寫(xiě)入文件或者數(shù)據(jù)庫(kù)的時(shí)候,再指定寫(xiě)入的編碼格式,用好這個(gè)準(zhǔn)則,我們可以避免百分之九十的編碼問(wèn)題。

HTTP響應(yīng)的數(shù)據(jù)格式有很多,例如文本、json、html,對(duì)應(yīng)的解析方式也很多。通用一點(diǎn),用python內(nèi)置庫(kù)正則匹配找到想要的數(shù)據(jù),但是這種方法相對(duì)來(lái)說(shuō)比較麻煩,而且不好維護(hù),比較適合文本類(lèi)型的數(shù)據(jù),但HTTP響應(yīng)正文基本都是json和HTML,這種方式適用面比較窄。

當(dāng)請(qǐng)求的數(shù)據(jù)是json格式時(shí),我們可以很方便的用requests反序列化返回內(nèi)容,取出感興趣的數(shù)據(jù)。但是當(dāng)HTTP返回的數(shù)據(jù)是html的時(shí)候,我們?cè)撊绾尾僮?,就像剛才知乎登陸的例子中,如何快速?gòu)膆tml中解析想要的數(shù)據(jù)呢?

專(zhuān)門(mén)用來(lái)解析html的第三方庫(kù)有很多,例如beautifulsoup、pyquery。個(gè)人推薦使用pyquery,因?yàn)樗梢允褂胘query的方式選取元素,而且支持xpath,以后上手scrapy會(huì)很容易。繼續(xù)上面登陸知乎的例子,登陸時(shí)需要的_xsrf實(shí)際上在 https://www.zhihu.com/#signin 頁(yè)面里面,只要先請(qǐng)求到這個(gè)頁(yè)面,然后解析出_xsrf,配合之前的登陸請(qǐng)求,我們就可以完整的實(shí)現(xiàn)用python模擬瀏覽器登陸知乎了。

python爬蟲(chóng)入門(mén)基本知識(shí)

python爬蟲(chóng)入門(mén)基本知識(shí)

使用起來(lái)是不是相當(dāng)?shù)暮?jiǎn)單,我們只要通過(guò)谷歌瀏覽器找到對(duì)應(yīng)DOM元素,根據(jù)屬性名就可以非??焖俚恼业较胍臄?shù)據(jù)。需要注意的是response.content和response.text,這都是返回的body正文,但是前者是bytes,后者是str,requests已經(jīng)幫助我們把響應(yīng)正文按照正確的編碼格式進(jìn)行了解碼,根據(jù)我們之前的闡述的原則,盡量使用str,所以26這個(gè)地方我用的是response.text。

更多關(guān)于pyquery的使用可以參考官方文檔: https://pythonhosted.org/pyquery/

存儲(chǔ)數(shù)據(jù)

根據(jù)數(shù)據(jù)量的不同以及數(shù)據(jù)類(lèi)型的不同,數(shù)據(jù)的存儲(chǔ)選擇也很多。如果爬取的是圖片、音頻、視頻等多媒體文件,直接按照文件形式存儲(chǔ)就好了。如果是一些文本,數(shù)字等數(shù)據(jù),一般有這么幾種選擇:

  • 輸出到屏幕
  • 寫(xiě)入文件(txt csv)
  • 寫(xiě)入數(shù)據(jù)庫(kù) (mysql sqlite mongo)

如果數(shù)據(jù)量非常小,可以選擇直接輸出到屏幕(這種情況貌似也不需要爬蟲(chóng)),因?yàn)榻K端存儲(chǔ)的數(shù)據(jù)量很少,而且因?yàn)闆](méi)有持久化,關(guān)閉窗口就意味著數(shù)據(jù)丟失,不建議使用。

在數(shù)據(jù)量小且不愿意折騰數(shù)據(jù)庫(kù)的情況下,可以把爬取的數(shù)據(jù)寫(xiě)入文件,但是這種情況不能隨取隨用,也不方便做數(shù)據(jù)分析,需要手動(dòng)處理。

當(dāng)數(shù)據(jù)量較多,而且需要快捷的分析數(shù)據(jù),推薦使用數(shù)據(jù)庫(kù)存儲(chǔ)數(shù)據(jù),大型的數(shù)據(jù)庫(kù)mysql, mongo功能齊全,可以分方便的進(jìn)行數(shù)據(jù)分析,而且也很容易實(shí)現(xiàn)分布式擴(kuò)展,當(dāng)你需要多進(jìn)程甚至多機(jī)器運(yùn)行爬蟲(chóng)的時(shí)候,這些數(shù)據(jù)庫(kù)可能是最好的選擇。sqlite相對(duì)來(lái)說(shuō)功能要少很多,python原生支持,依賴(lài)少,數(shù)據(jù)量不算太大的情況下可以考慮使用。

爬蟲(chóng)示例

下面給出一個(gè)簡(jiǎn)單的例子,為大家展示如何使用上述python庫(kù)實(shí)現(xiàn)一個(gè)完整的爬蟲(chóng)。一些熱門(mén)的知乎話(huà)題最多有1000條精華回答,這個(gè)例子就是爬取這些精品答案。圖示頁(yè)面就是回答列表,每頁(yè)有二十個(gè)答案,最多有五十頁(yè)。但是此頁(yè)面沒(méi)有完整的回答信息,需要通過(guò)顯示全部對(duì)應(yīng)的鏈接進(jìn)入回答詳情頁(yè)才能獲取完整的答案,所以我們的爬蟲(chóng)策略就是通過(guò)回答列表找到所有精華回答鏈接,再通過(guò)回答鏈接獲取內(nèi)容。而且這些頁(yè)面不需要登陸也能訪(fǎng)問(wèn),因此可以省去模擬登陸。

python爬蟲(chóng)入門(mén)基本知識(shí)

開(kāi)發(fā)環(huán)境

python是跨平臺(tái)語(yǔ)言,但不同平臺(tái)不同版本的python略微有一些差異,考慮到大家使用windows平臺(tái)的較多,我在windows和ubuntu的python3.5驗(yàn)證過(guò)此代碼,其他平臺(tái)和其他python版本下可能需要做一些修改。集成開(kāi)發(fā)環(huán)境推薦使用Pycharm,這是一個(gè)跨平臺(tái)良心IDE,各大操作系統(tǒng)下都有免費(fèi)的社區(qū)版本可以下載。

運(yùn)行代碼

代碼鏈接

https://github.com/LiuRoy/sakura/blob/master/spider/crawl.py

https://github.com/LiuRoy/sakura/blob/master/spider/tables.sql

安裝依賴(lài)庫(kù):

  1. pip install requests pyquery SQLAlchemy 

運(yùn)行代碼:

  1. python scrawl.py 

代碼解釋

通過(guò)谷歌瀏覽器抓包分析,可以通過(guò) https://www.zhihu.com/topic/19553155/top-answers?page=2 頁(yè)面獲取每個(gè)話(huà)題不同分頁(yè)下的回答鏈接 https://www.zhihu.com/question/27189372/answer/38712987 ,在此頁(yè)面中就可以獲取問(wèn)題、回答、點(diǎn)贊數(shù)、標(biāo)簽等信息。

因?yàn)閿?shù)據(jù)量不大,采用sqlite存儲(chǔ),可以很方便的用命令行或者桌面客戶(hù)端查看數(shù)據(jù)。

python爬蟲(chóng)入門(mén)基本知識(shí)

反爬蟲(chóng)策略和應(yīng)對(duì)方式

稍微大一些的網(wǎng)站都會(huì)有一些反爬蟲(chóng)策略,簡(jiǎn)單一點(diǎn)的根據(jù)User-Agent過(guò)濾,例如知乎,我們只需要設(shè)置為和瀏覽器相同即可。復(fù)雜一點(diǎn)的會(huì)限制非登陸用戶(hù),也只需要按照之前例子中的方式登陸,或者干脆先用瀏覽器登陸好,然后在第一次訪(fǎng)問(wèn)的時(shí)候帶上瀏覽器中的cookie就好,實(shí)現(xiàn)起來(lái)難度不大。但是有不少網(wǎng)站,例如豆瓣和github,在檢測(cè)到某一客戶(hù)端頻繁訪(fǎng)問(wèn)后,會(huì)直接封鎖ip,這個(gè)問(wèn)題解決起來(lái)就相當(dāng)?shù)募趾偷疤哿恕?/p>

解決方法也挺簡(jiǎn)單,我們只需要找到足夠多的代理ip就可以了,只要策略得當(dāng),短時(shí)間內(nèi)不要過(guò)度頻繁的使用同一ip代碼,或者當(dāng)某一ip地址被封鎖后馬上切換到其他的ip代理,這樣就可以保證高效的爬取數(shù)據(jù)了。那如何找到代理ip并且如何使用了,其實(shí)免費(fèi)的代理ip很多,我們用百度搜索代理ip就可以找到很多網(wǎng)站,例如:http://www.ip181.com/。

python爬蟲(chóng)入門(mén)基本知識(shí)

python爬蟲(chóng)入門(mén)基本知識(shí)

找到代理ip后,就可以用上面的方式很輕松的使用代理ip了,但是網(wǎng)上免費(fèi)的代理ip質(zhì)量不好,很多不可用,而且速度慢、不穩(wěn)定,請(qǐng)求的時(shí)候最好設(shè)置一下超時(shí)時(shí)間。我之前在爬github的時(shí)候,會(huì)專(zhuān)門(mén)寫(xiě)一個(gè)爬蟲(chóng)從這些網(wǎng)站搜集代理ip地址,一旦檢測(cè)到被github封鎖,就隨機(jī)選取一個(gè)代理ip使用,如果發(fā)現(xiàn)代理ip不可用,不斷的更換知道可用的代理ip為止,每個(gè)代理ip使用的次數(shù)也會(huì)有一定的限制,保證爬蟲(chóng)在整個(gè)執(zhí)行期間不會(huì)因?yàn)閕p封鎖而不可用。

異常及性能

曾經(jīng)我遇到過(guò)這樣的狀態(tài),寫(xiě)好并運(yùn)行爬蟲(chóng)一個(gè)小時(shí)之后,因?yàn)榫W(wǎng)絡(luò)抖動(dòng)或者某一種特殊的頁(yè)面導(dǎo)致解析失敗,整個(gè)爬蟲(chóng)運(yùn)行終止,這就蛋疼了。如果日志打印不充分,我連運(yùn)行失敗的原因都清楚,更別說(shuō)修復(fù)問(wèn)題,即使修復(fù)好重新運(yùn)行,又要花一個(gè)小時(shí)才能到剛才的進(jìn)度,費(fèi)時(shí)費(fèi)力。

爬蟲(chóng)出現(xiàn)異常的情況實(shí)在是太多:網(wǎng)絡(luò)抖動(dòng)、解析頁(yè)面失敗、反爬蟲(chóng)被屏蔽、寫(xiě)入數(shù)據(jù)異常、代碼邏輯錯(cuò)誤等等都會(huì)導(dǎo)致進(jìn)程終止,而一般爬蟲(chóng)需要數(shù)小時(shí)甚至數(shù)天數(shù)周的運(yùn)行,每一次的運(yùn)行失敗都是時(shí)間巨大的浪費(fèi)。因此一定需要在可能出現(xiàn)異常的地方接住異常,保證爬蟲(chóng)不會(huì)終止,并記錄日志,這些錯(cuò)誤日志不僅可以快速的幫助我們定位錯(cuò)誤,在出錯(cuò)不多的情況下,我們甚至不需要修改代碼重新運(yùn)行,只需要人肉補(bǔ)全這些數(shù)據(jù)就好。

如果發(fā)現(xiàn)自己的爬蟲(chóng)運(yùn)行效率太低,爬取速度太慢,并發(fā)對(duì)于提升爬蟲(chóng)速度是一個(gè)不錯(cuò)解決方案,因?yàn)镚IL的存在,多進(jìn)程并發(fā)模式對(duì)于python提速更優(yōu),我們可以使用生產(chǎn)者消費(fèi)者的模式將爬蟲(chóng)任務(wù)進(jìn)行拆分,從而實(shí)現(xiàn)多進(jìn)程或者分布式。一般來(lái)說(shuō)可以將HTTP請(qǐng)求的數(shù)據(jù)、解析數(shù)據(jù)、存儲(chǔ)數(shù)據(jù)分別用不同的進(jìn)程實(shí)現(xiàn),這些進(jìn)程之間通過(guò)消息隊(duì)列進(jìn)行通信,保證每個(gè)進(jìn)程無(wú)狀態(tài),就可以非常容易的實(shí)現(xiàn)多進(jìn)程擴(kuò)展。即使某一類(lèi)進(jìn)程出現(xiàn)異常,也不需要重新啟動(dòng)所有的進(jìn)程,只需要修復(fù)好代碼重新啟動(dòng),就可以實(shí)現(xiàn)斷點(diǎn)續(xù)爬了。

一些常用的分布式工具:redis、rabbitmq、scrapy、celery、you-get

責(zé)任編輯:未麗燕 來(lái)源: 36大數(shù)據(jù)
相關(guān)推薦

2011-11-23 10:35:53

2010-07-28 15:52:00

Flex

2017-10-20 22:40:54

電線(xiàn)電纜導(dǎo)體

2009-06-26 14:42:08

2009-06-11 14:40:32

Java list

2009-12-22 14:43:38

Linux操作系統(tǒng)

2010-01-28 11:18:14

Android界面布局

2010-05-06 17:41:19

Unix命令

2010-06-13 13:49:14

2012-06-05 00:41:07

JavaJava內(nèi)存

2017-02-20 23:05:14

JavaScript

2009-08-28 16:53:05

C# for語(yǔ)句

2010-06-17 13:22:40

UML用例建模

2010-04-21 18:38:36

Unix網(wǎng)絡(luò)

2010-06-10 11:41:57

MPLS協(xié)議棧結(jié)構(gòu)

2011-04-29 13:50:32

激光打印機(jī)

2012-05-08 09:10:56

WCF

2020-07-20 07:10:44

數(shù)據(jù)中心IT技術(shù)

2010-05-07 18:03:21

Unix服務(wù)器

2010-05-25 14:05:52

MySQL數(shù)據(jù)庫(kù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)