很多人剛學(xué)爬蟲的時(shí)候就想寫一些難度較大的爬蟲,其實(shí)有些操之過急对供。在此位他,我認(rèn)為應(yīng)該先明白以下幾點(diǎn),再來研究爬蟲才能更加水到渠成产场。
1鹅髓、理解HTTP請(qǐng)求。
2涝动、瀏覽器上所看見的頁面基本上都是由js腳本處理過的數(shù)據(jù)迈勋,與程序所得到的數(shù)據(jù)有所偏差。
3醋粟、如何巧用谷歌瀏覽器的開發(fā)者工具進(jìn)行調(diào)試靡菇。
1、理解HTTP請(qǐng)求:
HTTP請(qǐng)求是基于TCP/IP協(xié)議的應(yīng)用層協(xié)議米愿,請(qǐng)求方法常用的有GET厦凤、HEAD、POST育苟。默認(rèn)的請(qǐng)求方式為GET较鼓。所以一開始我們接觸爬蟲的時(shí)候會(huì)寫上一段這樣子的代碼:
import requests
resp = requests.get('http://www.baidu.com')
其中就是使用了HTTP的GET請(qǐng)求。
這樣一個(gè)小小的請(qǐng)求在這里之所以看似簡(jiǎn)單,是因?yàn)樵趓equests庫的背后已經(jīng)將很多細(xì)節(jié)都幫封裝好了博烂。
GET用于信息獲取香椎,GET請(qǐng)求報(bào)文示例:
GET /example?params=1 HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Connection: Keep-Alive
可以看到第一行已經(jīng)包括了請(qǐng)求方法,請(qǐng)求路徑禽篱,協(xié)議的版本畜伐。
而其他行如Host、User-Agent躺率、Connection等則表示請(qǐng)求時(shí)的一些條件:
Host 表示請(qǐng)求的域名
User-Agent 表示你所用的瀏覽器(這個(gè)在寫爬蟲時(shí)就可以偽造一番了)
Connection 表示要保持連接狀態(tài)玛界,及TCP/IP協(xié)議的連接狀態(tài)
還有其他請(qǐng)求條件如Cookie,Referer等等這里不再一一列舉悼吱,讀者可自行百度慎框。
不僅有GET請(qǐng)求,還有POST也很常用到后添。
POST請(qǐng)求一般用于提交數(shù)據(jù)較多笨枯,需要較強(qiáng)安全性的數(shù)據(jù)。使用場(chǎng)景一般是登陸遇西,上傳文件之類的操作猎醇。
POST請(qǐng)求的請(qǐng)求頭和GET類似的,唯一比較不一樣的是數(shù)據(jù)提交方式努溃,比如登陸時(shí)要提交郵箱和密碼:
GET請(qǐng)求的數(shù)據(jù)會(huì)附在URL之后,以?分割URL和傳輸數(shù)據(jù)阻问,多個(gè)參數(shù)用&連接梧税;例如:/login.php?email=123@qq.com&password=123
POST請(qǐng)求把提交的數(shù)據(jù)放置在是HTTP包的包體中。郵箱和密碼就是實(shí)際的傳輸數(shù)據(jù)被封裝在請(qǐng)求體中称近,因此第队,GET提交的數(shù)據(jù)會(huì)在地址欄中顯示出來,而POST提交刨秆,地址欄不會(huì)改變凳谦。
使用POST的代碼可以如下:
import requests
data = {
'email': '123@qq.com',
'password': '123'
}
resp = requests.post('https://www.zhihu.com/login/email', data=data) # 簡(jiǎn)單事例,實(shí)際運(yùn)用過程會(huì)更復(fù)雜
這樣就把郵箱密碼提交上去了衡未。
除了請(qǐng)求頭尸执,還有HTTP的響應(yīng)頭,響應(yīng)頭會(huì)包含一些服務(wù)器的時(shí)間缓醋,類型如失,還有相應(yīng)內(nèi)容的長(zhǎng)度等等。主要被用到的還是響應(yīng)頭中的狀態(tài)碼送粱。狀態(tài)碼有以下幾種類型:
2xx:成功--表示請(qǐng)求已被成功接收褪贵、理解、接受
3xx:重定向--要完成請(qǐng)求必須進(jìn)行更進(jìn)一步的操作
4xx:客戶端錯(cuò)誤--請(qǐng)求有語法錯(cuò)誤或請(qǐng)求無法實(shí)現(xiàn)
5xx:服務(wù)器端錯(cuò)誤--服務(wù)器未能實(shí)現(xiàn)合法的請(qǐng)求
常見狀態(tài)代碼、狀態(tài)描述脆丁、說明:
200 OK #客戶端請(qǐng)求成功
400 Bad Request #客戶端請(qǐng)求有語法錯(cuò)誤世舰,不能被服務(wù)器所理解
401 Unauthorized #請(qǐng)求未經(jīng)授權(quán),這個(gè)狀態(tài)代碼必須和WWW-Authenticate報(bào)頭域一起使用
403 Forbidden #服務(wù)器收到請(qǐng)求槽卫,但是拒絕提供服務(wù)
404 Not Found #請(qǐng)求資源不存在跟压,eg:輸入了錯(cuò)誤的URL
500 Internal Server Error #服務(wù)器發(fā)生不可預(yù)期的錯(cuò)誤
503 Server Unavailable #服務(wù)器當(dāng)前不能處理客戶端的請(qǐng)求,一段時(shí)間后可能恢復(fù)正常
這個(gè)狀態(tài)碼我們寫程序的時(shí)候可以怎么利用呢晒夹?
import requests
resp = requests.get('http://www.baidu.com')
if resp.status_code == 200:
print('響應(yīng)成功裆馒!')
這個(gè)狀態(tài)碼可以判斷我們?cè)诔绦虻恼?qǐng)求是否正常響應(yīng),方便程序排除錯(cuò)誤丐怯。
還有更多的響應(yīng)信息喷好,越是了解對(duì)寫爬蟲越是方便快捷
2、瀏覽器上所看見的頁面基本上都是由js腳本處理過的數(shù)據(jù)读跷,與程序所得到的數(shù)據(jù)有所偏差梗搅。
在谷歌瀏覽器中,右鍵有個(gè)檢查選項(xiàng)可以定位查看到當(dāng)前的html代碼效览,很多人認(rèn)為這也是我們程序中看到的html代碼无切。
這也就導(dǎo)致了一些新手朋友在學(xué)習(xí)時(shí)常常碰壁,以為是自己的selector寫錯(cuò)丐枉,其實(shí)主要原因還在于標(biāo)題所述的那樣哆键,你所看到的代碼一個(gè)被js處理過,另一個(gè)是服務(wù)器最初響應(yīng)給我們的數(shù)據(jù)瘦锹。
所以籍嘹,如果想查看網(wǎng)頁的最初的響應(yīng)數(shù)據(jù),可以右鍵查看源代碼弯院,這個(gè)源代碼也是沒有被js加工處理過的辱士,這時(shí)就可以利用這個(gè)源代碼進(jìn)行調(diào)試寫selector了。
3听绳、如何巧用谷歌瀏覽器的開發(fā)者工具進(jìn)行調(diào)試颂碘。
谷歌的開發(fā)者工具不僅是適用開發(fā)人員,而且對(duì)我們寫爬蟲也非常有益處椅挣。
按F12可以快速打開開發(fā)者工具头岔,可以看到有Elements、Console贴妻、Sources切油、Network等等。
其中Elements里面就是js加工處理過的代碼名惩,我們可以利用它來查找我們所要的標(biāo)簽中是否有價(jià)值的class或者id澎胡,如果有的話可以很快寫出selector。
Sources里存著網(wǎng)頁中如js,css大大小小的文件等等攻谁。
Network在抓取異步請(qǐng)求的數(shù)據(jù)時(shí)非常好用稚伍,Network中會(huì)包含很多異步請(qǐng)求,一般我們?cè)趧偞蜷_的時(shí)候是空的戚宦,這時(shí)刷新一下就會(huì)看到很多請(qǐng)求个曙,里面還可以看到請(qǐng)求頭、響應(yīng)頭等的信息受楼,非常方便垦搬。