網(wǎng)絡(luò )爬蟲(chóng)的原理
優(yōu)采云 發(fā)布時(shí)間: 2020-05-18 08:02互聯(lián)網(wǎng)上,公開(kāi)數據(各種網(wǎng)頁(yè))都是以http(或加密的http即https)協(xié)議傳輸的。所以,我們這兒介紹的爬蟲(chóng)技術(shù)都是基于http(https)協(xié)議的爬蟲(chóng)。
在Python的模塊海洋里,支持http合同的模塊是相當豐富的,既有官方的urllib,也有大名鼎鼎的社區(第三方)模塊 requests。它們都挺好的封裝了http合同懇求的各類(lèi)方式,因此,我們只須要熟悉這種模塊的用法,不再進(jìn)一步討論http合同本身。
大家對瀏覽器應當一點(diǎn)都不陌生,可以說(shuō),只要上過(guò)網(wǎng)的人都曉得瀏覽器??墒?,明白瀏覽器各類(lèi)原理的人可不一定多。
作為要開(kāi)發(fā)爬蟲(chóng)的小伙伴網(wǎng)絡(luò )爬蟲(chóng)原理,是一定一定要明白瀏覽器的工作原理的。這是你寫(xiě)爬蟲(chóng)的必備工具,別無(wú)他。
大家在筆試的時(shí)侯,有沒(méi)有遇見(jiàn)如此一個(gè)特別宏觀(guān)而又處處細節的解答題:
這真是一個(gè)考驗知識面的題啊,經(jīng)驗老道的老猿既可以滔滔不絕的講上三天三夜,也可以提煉出幾分鐘的精華講個(gè)大約。大家似乎對整個(gè)過(guò)程就一知半解了。
巧的是,對這個(gè)問(wèn)題理解的越透徹,越對寫(xiě)爬蟲(chóng)有幫助。換句話(huà)說(shuō),爬蟲(chóng)是一個(gè)考驗綜合技能的領(lǐng)域。那么,大家打算好迎接這個(gè)綜合技能挑戰了嗎?
廢話(huà)不多說(shuō),我們就從解答這個(gè)題目開(kāi)始,認識瀏覽器和服務(wù)器,看看這中間有什么知識是爬蟲(chóng)要用到的。
前面也說(shuō)過(guò),這個(gè)問(wèn)題可以講上三天三夜,但我們沒(méi)那么多時(shí)間,其中一些細節就略過(guò),把大致流程結合爬蟲(chóng)講一講,分成三部份:
瀏覽器發(fā)出懇求服務(wù)器作出響應瀏覽器接收響應
在瀏覽器地址欄輸入網(wǎng)址后回車(chē),瀏覽器請服務(wù)器提出網(wǎng)頁(yè)懇求,也就是告訴服務(wù)器,我要看你的某個(gè)網(wǎng)頁(yè)。 上面短短一句話(huà),蘊藏了無(wú)數玄機啊,讓我不得不費點(diǎn)口舌一一道來(lái)。主要述說(shuō):
首先,瀏覽器要判定你輸入的網(wǎng)址(URL)是否合法有效。對應URL網(wǎng)絡(luò )爬蟲(chóng)原理,小猿們并不陌生吧,以http(s)開(kāi)頭的那一長(cháng)串的字符,但是你曉得它還可以以ftp, mailto, file, data, irc開(kāi)頭嗎?下面是它最完整的句型格式:
URI = scheme:[//authority]path[?query][#fragment]
# 其中, authority 又是這樣的:
authority = [userinfo@]host[:port]
# userinfo可以同時(shí)包含user name和password,以:分割
userinfo = [user_name:password]
用圖更形象的表現處理就是這樣的:
經(jīng)驗之談:要判定URL的合法性
Python上面可以用urllib.parse來(lái)進(jìn)行URL的各類(lèi)操作
In [1]: import urllib.parse
In [2]: url = 'http://dachong:the_password@www.yuanrenxue.com/user/info?page=2'
In [3]: zz = urllib.parse.urlparse(url)
Out[4]: ParseResult(scheme='http', netloc='dachong:the_password@www.yuanrenxue.com', path='/user/info', params='', query='page=2', fragment='')
我們看見(jiàn),urlparse函數把URL剖析成了6部分: scheme://netloc/path;params?query#fragment 需要主要的是 netloc 并不等同于 URL 語(yǔ)法定義中的host
上面URL定義中的host,就是互聯(lián)網(wǎng)上的一臺服務(wù)器,它可以是一個(gè)IP地址,但一般是我們所說(shuō)的域名。域名通過(guò)DNS綁定到一個(gè)(或多個(gè))IP地址上。瀏覽器要訪(fǎng)問(wèn)某個(gè)域名的網(wǎng)站就要先通過(guò)DNS服務(wù)器解析域名,得到真實(shí)的IP地址。 這里的域名解析通常是由操作系統完成的,爬蟲(chóng)不需要關(guān)心。然而,當你寫(xiě)一個(gè)小型爬蟲(chóng),像Google、百度搜索引擎那樣的爬蟲(chóng)的時(shí)侯,效率顯得太主要,爬蟲(chóng)就要維護自己的DNS緩存。 老猿經(jīng)驗:大型爬蟲(chóng)要維護自己的DNS緩存
瀏覽器獲得了網(wǎng)站服務(wù)器的IP地址,就可以向服務(wù)器發(fā)送懇求了。這個(gè)懇求就是遵守http合同的。寫(xiě)爬蟲(chóng)須要關(guān)心的就是http合同的headers,下面是訪(fǎng)問(wèn) en.wikipedia.org/wiki/URL 時(shí)瀏覽器發(fā)送的懇求 headers:
可能早已從圖中看下來(lái)些疲態(tài),發(fā)送的http請求頭是類(lèi)似一個(gè)字典的結構:
path: 訪(fǎng)問(wèn)的網(wǎng)站的路徑scheme: 請求的合同類(lèi)型,這里是httpsaccept: 能夠接受的回應內容類(lèi)型(Content-Types)accept-encoding: 能夠接受的編碼方法列表accept-language: 能夠接受的回應內容的自然語(yǔ)言列表cache-control: 指定在此次的請求/響應鏈中的所有緩存機制 都必須 遵守的指令cookie: 之前由服務(wù)器通過(guò) Set- Cookie發(fā)送的一個(gè) 超文本傳輸協(xié)議Cookie 這是爬蟲(chóng)太關(guān)心的一個(gè)東東,登錄信息都在這里。upgrade-insecuree-requests: 非標準懇求數組,可忽視之。user-agent: 瀏覽器身分標示
這也是爬蟲(chóng)太關(guān)心的部份。比如,你須要得到手機版頁(yè)面,就要設置瀏覽器身分標示為手機瀏覽器的user-agent。
經(jīng)驗之談: 通過(guò)設置headers跟服務(wù)器溝通
如果我們在瀏覽器地址欄輸入一個(gè)網(wǎng)頁(yè)網(wǎng)址(不是文件下載地址),回車(chē)后,很快就聽(tīng)到了一個(gè)網(wǎng)頁(yè),里面包含排版文字、圖片、視頻等數據,是一個(gè)豐富內容格式的頁(yè)面。然而,我通過(guò)瀏覽器查看源代碼,看到的卻是一對文本格式的html代碼。
沒(méi)錯,就是一堆的代碼,卻使瀏覽器給渲染成了漂亮的網(wǎng)頁(yè)。這對代碼上面有:
而我們想要爬取的信息就藏在html代碼中,我們可以通過(guò)解析方式提取其中我們想要的內容。如果html代碼上面沒(méi)有我們想要的數據,但是在網(wǎng)頁(yè)上面卻看見(jiàn)了,那就是瀏覽器通過(guò)ajax懇求異步加載(偷偷下載)了那部份數據。


