爬蟲(chóng)用python寫(xiě)網(wǎng)絡(luò)_第1頁(yè)
爬蟲(chóng)用python寫(xiě)網(wǎng)絡(luò)_第2頁(yè)
爬蟲(chóng)用python寫(xiě)網(wǎng)絡(luò)_第3頁(yè)
爬蟲(chóng)用python寫(xiě)網(wǎng)絡(luò)_第4頁(yè)
爬蟲(chóng)用python寫(xiě)網(wǎng)絡(luò)_第5頁(yè)
已閱讀5頁(yè),還剩164頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

內(nèi)容提內(nèi)容提本書(shū)講解了如何使用P川lOil來(lái)編寫(xiě)網(wǎng)絡(luò)爬蟲(chóng)程序,內(nèi)容包括網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)介,從頁(yè)面中抓取數(shù)據(jù)的三種方法,提取緩存中的數(shù)據(jù),使用多個(gè)線程和進(jìn)程來(lái)進(jìn)行并發(fā)抓取,如何抓取動(dòng)態(tài)頁(yè)面中的內(nèi)容,與表單進(jìn)行交互,處理頁(yè)面中的驗(yàn)證碼問(wèn)題以及使ScarpyPortia來(lái)進(jìn)行數(shù)據(jù)抓取,并在最后使用本書(shū)介紹的數(shù)據(jù)抓取技術(shù)對(duì)幾個(gè)真實(shí)的網(wǎng)站進(jìn)行了抓取,旨在幫助讀者活學(xué)活用書(shū)中介紹的技術(shù)。本書(shū)適合有一定Python編程經(jīng)驗(yàn),而且對(duì)爬蟲(chóng)技術(shù)感興趣的讀者閱讀關(guān)于作來(lái)自澳大利亞關(guān)于作來(lái)自澳大利亞畢業(yè)于墨爾本大學(xué)計(jì)算機(jī)科學(xué)專業(yè)。業(yè)后,他創(chuàng)辦了一家專注于網(wǎng)絡(luò)爬蟲(chóng)的公司,為超過(guò)50個(gè)國(guó)家的業(yè)務(wù)提供遠(yuǎn)程工作。他精通于世界語(yǔ),可以使用漢語(yǔ)和韓語(yǔ)對(duì)話,并且積極投身于開(kāi)源軟件。他目前在牛津大學(xué)攻讀研究生學(xué)位,并利用業(yè)余時(shí)間研發(fā)自主無(wú)人機(jī)我要感謝TimothyBaldwin教授將我引入這個(gè)令人興奮的領(lǐng)域本書(shū)編寫(xiě)時(shí)在巴黎招待我的ηiara可Douc以關(guān)于審稿Bur咄是一名常駐紐約的數(shù)據(jù)記者,關(guān)于審稿Bur咄是一名常駐紐約的數(shù)據(jù)記者,其工作是為華爾街日?qǐng)?bào)繪交互式圖表。他在新墨西哥州立大學(xué)獲得了新聞學(xué)和信息系統(tǒng)專業(yè)位,然后在紐約城市大學(xué)新聞學(xué)研究院獲得了新聞學(xué)專業(yè)碩士學(xué)位我要感謝我的妻子isa鼓勵(lì)我協(xié)助本書(shū)的創(chuàng)作,的叔叔Mica耐心解答我的編程問(wèn)題, 以及我的父親Richard激發(fā)了我對(duì)新聞學(xué)和寫(xiě)作的熱愛(ài)WilliamSankey是一位數(shù)據(jù)專業(yè)人士,也是一位業(yè)余開(kāi)發(fā)人員,生活在里蘭州科利奇帕克市。他于2012年畢業(yè)于約翰·霍普金斯大學(xué),獲得了公政策碩士學(xué)位,專業(yè)方向?yàn)槎糠治?。他目前?政策研究有限責(zé)任公&擔(dān)任健康服務(wù)研究員,從事與美國(guó)醫(yī)療保險(xiǎn)和醫(yī)療補(bǔ)助服務(wù)中心(CMS)相關(guān)的項(xiàng)目。這些項(xiàng)目包括責(zé)任醫(yī)療機(jī)構(gòu)評(píng)估以及精神病院住院患者預(yù)統(tǒng)監(jiān)測(cè)我要感謝我深愛(ài)的妻子Julia和頑皮的小貓Ruby,給予我全部的愛(ài)和AyushTiwari是一名Python開(kāi)發(fā)者,本科就讀AyushTiwari是一名Python開(kāi)發(fā)者,本科就讀于印度工學(xué)院羅克分校。發(fā)領(lǐng)域。對(duì)他而言,審閱本書(shū)是一個(gè)非常棒的經(jīng)歷。他不僅是一名審稿人,也是一名狂熱的網(wǎng)絡(luò)爬蟲(chóng)學(xué)習(xí)者。他向所有Python愛(ài)好者推薦本書(shū),以便享他熱衷于Python網(wǎng)絡(luò)爬蟲(chóng),曾參與體育直播訂閱、通用P川lil電子商務(wù)網(wǎng)絡(luò)爬蟲(chóng)(在Miran相關(guān)項(xiàng)目。Djo應(yīng)用開(kāi)發(fā)了就業(yè)門戶,幫助改善印度工學(xué)院羅克分他還使用的就業(yè)流程除了后端開(kāi)發(fā)之外,他還喜歡使用諸如u上訪問(wèn)到他的項(xiàng)目,他的用戶名是tiwariayush。他喜歡徒步穿越喜馬拉雅山谷,每年會(huì)參加多次徒步行走活動(dòng)。此外,他還喜歡彈他的成就還包括參加國(guó)際知名Super30小組并在其中成為排名保持者。他在高中時(shí),還參加了國(guó)際奧林匹克數(shù)學(xué)競(jìng)賽。b我的家庭成員(我的姐姐Aditi、我的父母以及Anand先生)、我在VI和IMG的朋友以及我的教授都為我提供了很大的幫助。我要感謝他們所有人對(duì)我的支持。最后,感謝尊敬的ackt出版社團(tuán)隊(duì)出版了這些非常好的技術(shù)我要對(duì)他們?cè)诰帉?xiě)2..a.&.刷..a.&.刷互聯(lián)網(wǎng)包含了迄今為止最有用的數(shù)據(jù)集,并且大部分可以免費(fèi)公開(kāi)訪問(wèn)。但是,這些數(shù)據(jù)難以復(fù)用。它們被嵌入在網(wǎng)站的結(jié)構(gòu)和樣式當(dāng)中,需要抽取出來(lái)才能使用。從網(wǎng)頁(yè)中抽取數(shù)據(jù)的過(guò)程又被稱為網(wǎng)絡(luò)爬蟲(chóng)。隨著越來(lái)越的信息被發(fā)布到網(wǎng)絡(luò)上,網(wǎng)絡(luò)爬蟲(chóng)也變得越來(lái)越有用第1章,網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)介,介紹了網(wǎng)絡(luò)爬蟲(chóng),并講解了爬取網(wǎng)站的方法。第2章,數(shù)據(jù)抓取,展示了如何從網(wǎng)頁(yè)中抽取數(shù)據(jù)。第3章,下載緩存,學(xué)習(xí)了如何通過(guò)緩存結(jié)果避免重復(fù)下載的問(wèn)題。第4章,并發(fā)下載,通過(guò)并行下載加速數(shù)據(jù)抓取。第5章,動(dòng)態(tài)內(nèi)容示了如何從動(dòng)態(tài)網(wǎng)站中抽取數(shù)第6章,表單交互,展示了如何與表單進(jìn)行交互而訪問(wèn)你需要的數(shù)據(jù)。第7章,驗(yàn)證碼處理,闡述了如何訪問(wèn)被驗(yàn)證碼圖像保護(hù)的數(shù)據(jù)。第8Scrapy學(xué)習(xí)了如何使用流行的高級(jí)cay第9章結(jié),對(duì)我們介紹的這些網(wǎng)絡(luò)爬蟲(chóng)技術(shù)進(jìn)行總結(jié)前本書(shū)中所有的代碼都己經(jīng)在Python前本書(shū)中所有的代碼都己經(jīng)在Python環(huán)境中進(jìn)行過(guò)測(cè)試,并且可以http//bitbucket.og/wspcode下載到這些源代碼理想情況下本書(shū)未來(lái)的版本會(huì)將示例代碼移植到Python3當(dāng)中。不過(guò),現(xiàn)在依賴的很多庫(kù)(比如Scrapy/Twisted、Mechaize和Ghost)還只支持Python2。為了幫助闡明爬取示例我們創(chuàng)建了一個(gè)示例其http//xaple.webscraping.com。由于該網(wǎng)站限制了下載內(nèi)容的速度,因此如果你希望網(wǎng)站源代碼和安裝說(shuō)明。我們決定為本書(shū)中使用的大部分示例搭建一個(gè)定制網(wǎng)而不是抓取活躍網(wǎng)站,這樣我們就對(duì)環(huán)境擁有了完全控制。這種方式為我們提供了穩(wěn)定性,因?yàn)榛钴S網(wǎng)站要比書(shū)中的定制網(wǎng)站更新更加頻繁,并且當(dāng)你嘗試運(yùn)行爬蟲(chóng)示例時(shí),代碼可能已經(jīng)無(wú)法工作。另外,定制網(wǎng)站允許我們自定義示例,用于闡釋特定技巧并避免其他干擾。最后,活躍網(wǎng)站可能并不歡迎我們使用它作為學(xué)習(xí)網(wǎng)絡(luò)爬蟲(chóng)的對(duì)象,并且可能會(huì)嘗試封禁我們的爬蟲(chóng)。使用我們自己定制的網(wǎng)站可以規(guī)避這些風(fēng)險(xiǎn),不過(guò)在這些例子中學(xué)到的技巧確實(shí)也可以應(yīng)到這些活躍網(wǎng)站當(dāng)中閱讀本書(shū)需要有一定的編程經(jīng)驗(yàn),并且不適用于絕對(duì)的初學(xué)者。在實(shí)踐中我們將會(huì)首先實(shí)現(xiàn)我們自己的網(wǎng)絡(luò)爬蟲(chóng)技術(shù)版本,然后才會(huì)介紹現(xiàn)有的流行這樣可以讓你更好地理解這些技術(shù)是如何工作的。本書(shū)中的這些示例塊假設(shè)你已經(jīng)擁有Python語(yǔ)言以及使用pip安裝模塊的能力。如果你想復(fù)習(xí)一這些知識(shí) 有一本非常好的免費(fèi)在線書(shū)籍可以使用,其作者為2前Pilri前Pilrim書(shū)籍網(wǎng)址是httpwwwdvetopythonnet。這本書(shū)也是我此外,這些例子還假設(shè)你己經(jīng)了解網(wǎng)頁(yè)是如何使用HTML進(jìn)行構(gòu)建并過(guò)Jvcipt更新的知識(shí)的既有知識(shí)也很有用,不過(guò)它們不是必需的,這些技術(shù)會(huì)在需要使用時(shí)進(jìn)行介紹。上述很多主題的詳細(xì)參考資料可以從http://.w3schols.獲取到3第1網(wǎng)絡(luò)網(wǎng)絡(luò)爬蟲(chóng)是否合…………背景調(diào) 第1網(wǎng)絡(luò)網(wǎng)絡(luò)爬蟲(chóng)是否合…………背景調(diào) 檢查網(wǎng)站地 估算網(wǎng)站大 識(shí)別網(wǎng)站所用技術(shù)尋找網(wǎng)站所有 …編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)………8下載網(wǎng) I遍歷爬蟲(chóng)鏈接爬 本章小結(jié)… 第2數(shù)據(jù)抓分析網(wǎng) 三種網(wǎng)頁(yè)抓取方法正則表達(dá) 目BeautifuSoup·········………目BeautifuSoup·········………………………結(jié)論…………為鏈接爬蟲(chóng)添加抓取回 本章小 第3下載緩為鏈接爬蟲(chóng)添加緩存支持…·····················… 磁盤緩 實(shí) 緩存測(cè) 節(jié)省磁盤空間………………清理過(guò)期數(shù) 缺點(diǎn)…………·數(shù)據(jù)庫(kù)緩 NQL是什 …·…………安裝MongoD MongoDB緩存實(shí) 壓 緩存測(cè)…·”…………本章小結(jié)………第4并發(fā)下100萬(wàn)個(gè)網(wǎng) 串行爬 多線程爬 2目線程和進(jìn)程如何工 實(shí) 多進(jìn)程爬 性 目線程和進(jìn)程如何工 實(shí) 多進(jìn)程爬 性 本章小結(jié) 第5動(dòng)態(tài)內(nèi)動(dòng)態(tài)網(wǎng)頁(yè)示 對(duì)動(dòng)態(tài)網(wǎng)頁(yè)進(jìn)行逆向工程 渲染動(dòng)態(tài)網(wǎng) PyQt還是PySid 執(zhí)行JavaScri 使用WebKit與網(wǎng)站交 本章小 第6表單交第7登錄表 支持內(nèi)容更新的登錄腳本擴(kuò) 使Mechanize模塊實(shí)現(xiàn)自動(dòng)化表單處 本章小結(jié)1驗(yàn)證碼處注冊(cè)賬號(hào) …·光學(xué)字符識(shí)別處理復(fù)雜驗(yàn)證 111使用驗(yàn)證碼處理服 9kw入 3與注冊(cè)功能集成本章小結(jié) 第8與注冊(cè)功能集成本章小結(jié) 第8安 …··啟動(dòng)項(xiàng)目8.2.1定義模 l檢查結(jié) 中斷與恢復(fù)爬蟲(chóng)”…………8.38.3安裝………標(biāo)注優(yōu)化爬蟲(chóng) …·檢查結(jié)果 使用Scrapeyl實(shí)現(xiàn)自動(dòng)化抓 本章小結(jié)……………第9總’40O2章中,我們將章中,我們將會(huì)介紹如下主題解釋合法性質(zhì)疑對(duì)目標(biāo)網(wǎng)站進(jìn)行背景調(diào)研逐步完善一個(gè)高級(jí)網(wǎng)絡(luò)爬蟲(chóng)1.設(shè)我有并且想要及時(shí)了解競(jìng)爭(zhēng)對(duì)我可以每天訪問(wèn)他們的網(wǎng)站,與我店鋪中鞋子的價(jià)格進(jìn)行對(duì)比。但是,如果我店鋪中的鞋類品種繁多或是希望能夠更加頻繁地查看價(jià)格變化的話,就需要花費(fèi)大量的時(shí)間,甚至難以實(shí)現(xiàn)。再舉一個(gè)例子,我看中了一雙鞋,想等促銷時(shí)再購(gòu)買。我可能需要每天訪問(wèn)這家鞋店的網(wǎng)站來(lái)查看這雙鞋是否價(jià),也許需要等待幾個(gè)月的時(shí)間,我才能如愿盼到這雙鞋促銷上述兩個(gè)重復(fù)性的手工流程都可以利用本書(shū)介紹的網(wǎng)絡(luò)爬蟲(chóng)技術(shù)實(shí)現(xiàn)自動(dòng)處理1章網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)P,1章網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)P,P,但是它們通常會(huì)限制可以抓取的數(shù)據(jù),以及訪問(wèn)這些數(shù)據(jù)的頻率。另外對(duì)于網(wǎng)的開(kāi)發(fā)者而言維護(hù)前端界面比維護(hù)后端API接口優(yōu)先級(jí)更高??偽覀儾荒軆H僅依賴于API去訪問(wèn)我們所需的在線數(shù)據(jù)而是應(yīng)該學(xué)習(xí)些網(wǎng)絡(luò)爬蟲(chóng)技術(shù)的相關(guān)知識(shí)1網(wǎng)絡(luò)爬蟲(chóng)目前還處于早期的蠻荒階段,允許哪些行為”這種基本秩序還處于建設(shè)之中。從目前的實(shí)踐來(lái)看,如果抓取數(shù)據(jù)的行為用于個(gè)人使用,則不存在問(wèn)題而如果數(shù)據(jù)用于轉(zhuǎn)載那么抓取的數(shù)據(jù)類型就非常關(guān)鍵了。世界各地法院的一些案件可以幫助我們確定哪些網(wǎng)絡(luò)爬蟲(chóng)行為是允Co的案件中,在Feist的國(guó)聯(lián)邦最高法院裁定抓取并轉(zhuǎn)載真實(shí)數(shù)據(jù)(比如,電話清單〉是允許的。而在澳大TelstraCorporationLimited起訴PhoneDirectoriesCompanyLtd這一類似案件中,則裁定只有擁有明確作者的數(shù)據(jù),才可以獲得,是允許的最終裁定定期抓取和深度這些案件告訴我們,當(dāng)抓取的數(shù)據(jù)是現(xiàn)實(shí)生活中的真實(shí)數(shù)據(jù)(比如電話清單)時(shí),是允許轉(zhuǎn)載的。但是,如果是原創(chuàng)數(shù)據(jù)(比如,意地址和評(píng)論),通常就會(huì)受到版權(quán)限制,而不能轉(zhuǎn)載無(wú)論如何,當(dāng)你抓取某個(gè)網(wǎng)站的數(shù)據(jù)時(shí)記住自己是該網(wǎng)站的訪客,應(yīng)當(dāng)約束自己的抓取行為,否則他們可能會(huì)封禁你的IP甚至采取更進(jìn)一步的這就要求下載請(qǐng)求的速度需要限定在一個(gè)合理值之內(nèi) 并且還法律行要設(shè)定一個(gè)專屬的用戶代理來(lái)標(biāo)識(shí)自己。在下面的小節(jié)中我們將會(huì)對(duì)這些踐進(jìn)行具體介紹21關(guān)于上述幾個(gè)法律案件的更多信息可以參考下述地址?getcase.?http://www.bvhd.dk/uploads/tx/SogHandelsrettensafgrelseiOfir-1在深入討論爬取一個(gè)網(wǎng)站之前,我們首先1關(guān)于上述幾個(gè)法律案件的更多信息可以參考下述地址?getcase.?http://www.bvhd.dk/uploads/tx/SogHandelsrettensafgrelseiOfir-1在深入討論爬取一個(gè)網(wǎng)站之前,我們首先需要對(duì)目標(biāo)站點(diǎn)的規(guī)模和結(jié)構(gòu)行一定程度的了解。網(wǎng)站自身的robots們提供一定的幫助,此外還有一些能提供更詳細(xì)信息的外部工具,比如Goog1.3.1檢查站t,站時(shí)存在哪些限制。這些限制雖然僅僅作為建議給出,但是良好的網(wǎng)絡(luò)公民都應(yīng)當(dāng)遵守這些限制。在爬取之前,檢查rob.txt文件這一寶貴資源可以最小站相關(guān).們的示例文件robots.中的內(nèi)容可以訪問(wèn)httpexampwebscraping.co/ots.獲?。#?,戶--3aaBwoneq4tacasr·e1章網(wǎng)絡(luò)爬蟲(chóng)#sectionU1章網(wǎng)絡(luò)爬蟲(chóng)#sectionUser-agent:*Crawl-delay:5Disallow:/trap#sectionSitemap:http:///sitemap.Crl在sect爬蟲(chóng)爬取該網(wǎng)站,不過(guò)這種寫(xiě)法可能無(wú)法起到應(yīng)有的作用,因?yàn)閻阂馀老x(chóng)本不會(huì)遵從robots.txt的要求。章后面的一個(gè)子將會(huì)展示如何讓爬自動(dòng)遵守robots的要求section2規(guī)定,無(wú)論使用哪種用戶代理,都應(yīng)該在兩次下載請(qǐng)求之間給出5秒的抓取延遲,我們需要遵從該建議以避免服務(wù)器過(guò)載。這里還有一個(gè)trp鏈接用于封禁那些爬取了不允許鏈接的惡意爬蟲(chóng)。如果你訪問(wèn)了這個(gè)鏈接服務(wù)器就會(huì)封禁你的IP一分鐘!一個(gè)真實(shí)的網(wǎng)能會(huì)對(duì)你的IP封禁更長(zhǎng)時(shí)間至是永久封禁不過(guò)如果這樣設(shè)置的話我們就無(wú)法section3義了一個(gè)Sitemap文我們將在下一節(jié)中了解如何檢1.3.2檢查網(wǎng)站地圖網(wǎng)站提供的Stemap文件(即網(wǎng)站地圖)可以幫助爬蟲(chóng)定位網(wǎng)站最新的內(nèi)容而無(wú)須爬取每一個(gè)網(wǎng)頁(yè)。如果想要了解更多信息可以從http:wwwsitemapsorprtocol.htl獲取網(wǎng)圖標(biāo)的St<?xmlversion=1encoding=UTF8<urlsetxmlns=”httpwwwsitemapsorgschemassitemap/0.9<url><loc>http://example.webscraping.com/view/Afghanistan-</loc><<url><loc>http://example.webscraping.com/view/Aland-Islands-41</loc></url><url><loc>http:///view/Albania-3</1</loc></url><url><loc>http:///view/Albania-3</loc></urlset>網(wǎng)站地圖提供了所有網(wǎng)頁(yè)的鏈接,我們會(huì)在后面的小節(jié)中使用這些信息,用于創(chuàng)建我們的第一個(gè)爬蟲(chóng)。雖然Siemap文件提供了一種爬取網(wǎng)站的有效方式但是我們?nèi)孕鑼?duì)其謹(jǐn)慎處理因?yàn)樵撐募?jīng)常存在缺失整的問(wèn)題1.3.3估算網(wǎng)站大小目標(biāo)網(wǎng)大小會(huì)影響我們?nèi)绾芜M(jìn)行爬取如果是像我們的示這樣只有幾百個(gè)URL的網(wǎng)站,效率并沒(méi)有那么重要:但如果是擁有數(shù)百萬(wàn)個(gè)網(wǎng)頁(yè)的站點(diǎn),使用串行下載可能需要持續(xù)數(shù)月才能完成,這時(shí)就需要使用第4章站可能已經(jīng)爬取過(guò)我們感興趣的網(wǎng)。我們可以通過(guò)Goole搜索的site詞過(guò)濾域名結(jié)果,從而獲取該信息我們可以從http/w.search了解到該接口及其他高級(jí)搜索參數(shù)的用法com/adva口圖1.1所示為使用sie關(guān)鍵詞對(duì)我們的示例網(wǎng)站進(jìn)行搜索的結(jié)果Google中搜site:example.webscraping.即從圖1.1中可以看出此時(shí)Google估算該網(wǎng)擁有個(gè)網(wǎng)頁(yè),這和不過(guò)對(duì)于更大型的網(wǎng)站,我會(huì)發(fā)現(xiàn)Google的估算并不在域名后面添加URL路徑,可以對(duì)結(jié)果進(jìn)行過(guò)濾僅顯示網(wǎng)某些部分。1.2所示為搜siteexamplewebscrapingcomview的結(jié)果該搜索條件會(huì)限制Google只搜索國(guó)家頁(yè)面51第章網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)介Aboul202re田JltS伺45蕃AF?ExampleExam阱嗣b陽(yáng)叩ing\¥盹腳.Ar目,聞geria·Angela·senin·Sotswana·刷刷1第章網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)介Aboul202re田JltS伺45蕃AF?ExampleExam阱嗣b陽(yáng)叩ing\¥盹腳.Ar目,聞geria·Angela·senin·Sotswana·刷刷Fa回·6田undlC副陌roonca陽(yáng)Verde·C田11ra1Ari國(guó)nR邱刷lc·Chwebs掛NA-εxa『npleex翻F瑞E翼田胃pieweb缸萬(wàn)冒pir咱w雹』畫(huà)捶.IJ。曲ArAn竄山l國(guó)Anti凱iaar晴B酣budaSaintEus恒屈JSNE姐 scrapingNalklnalFl咽’M回:1,267,00S嗯且惜據(jù)陽(yáng)elli劇,問(wèn)pula如n:10,676,27專lso:Country:IJ脅,.Cai就醋’Nlam町C曲睛酣吐AF.Tlcl:J班CurCode:NG-Examplewebsαapinge刷腳.wet刷刷lisol閘NationalFl啕:島國(guó):923,768squa陽(yáng)鬧。metres.Pcψu(yù)l硝or應(yīng)154,00口,00.1聰C咀Jntry:N精制a巳apl國(guó)EAlli!由acon劇團(tuán)提:AFTld:.ngcurrencyC時(shí)居圖1.1About117明ults(0.52seamExampleweb部rapingNatio捕’F陸g:A,回:76squ町ekllom鈍國(guó).Population:65,22苗,i四:GG.Cou晴y.G佳emse于“CapitalStPeterp。她Con伽entEU.Tld:.gg.CurrencyCode:GBP.Examplewebscraping回am樹(shù)e.w唾民臼撞倒fv梅w/Je陀曹y-113Nat陽(yáng)nalF句:陽(yáng)明:116呵U腳扭llornet陽(yáng).P句“l(fā)a切罰;閡,612.lso:JE.Country:Jerse滬PK-scrapingFl句:A陌a:8部,S鉛squa用kfm悅s.Population:184,404,791.國(guó)C由mtry:Pak陸;tan.Cap幅:1時(shí)ama缸ad.Cont加劇1l:AS“l(fā)ld:.pkCurrencyCodewebsite-C皿miry:Ma姐ysia.Ca回國(guó):KualaL四npur.Con11nentAS.Tld:.my.C町rency町圖1這種附加的過(guò)濾條件非常有用,因?yàn)樵诶硐肭闆r下,你只希望爬取網(wǎng)站包含有用數(shù)據(jù)的部分,而不是爬取網(wǎng)站的每個(gè)頁(yè)面611識(shí)別網(wǎng)站所用構(gòu)建網(wǎng)站所使用的技術(shù)類型也會(huì)對(duì)我們?nèi)绾闻廊?1識(shí)別網(wǎng)站所用構(gòu)建網(wǎng)站所使用的技術(shù)類型也會(huì)對(duì)我們?nèi)绾闻廊‘a(chǎn)生影響。有一個(gè)十分有用的工具可以檢查網(wǎng)構(gòu)建的技術(shù)類型一-lwith模塊。該模塊的安裝pipinstallbuiltwi該模塊將URL為參數(shù)下載該URL并對(duì)其進(jìn)行分析,然后返回該網(wǎng)站使用的技術(shù)。下面是使用該模塊的一個(gè)例子?!罚緄mp。rtbuiltwi》>builtwith.parse(’http://example.webscraping.c。m’{ujavascriptfre。rks:[ujQl且ery,uM。dernizr,u’jQl且eryUI][u’Pyth。n’]u’pr。graming-languages’u’web-f。rks’ [u’Web2py’,u’TwitterB。。tstrap’]u’web-servers’:[u’Nginx’]從上面的返回結(jié)果中可以看出示例網(wǎng)用了Python的W2py框架,另外還使用了一些通用的Jvcript庫(kù),因此該網(wǎng)內(nèi)容很有可能是嵌在HML中的,相對(duì)而言比較容易抓取。而如果改用AngularJS構(gòu)建該網(wǎng),此時(shí)的網(wǎng)站內(nèi)容就很可能是動(dòng)態(tài)加載的。另外,如果網(wǎng)站使用了A.NET么在爬取網(wǎng)頁(yè)時(shí),就必須要用到會(huì)話管理和表單提交了。的情況,我們會(huì)在第5章和第6章中進(jìn)行介紹。對(duì)于這些更加復(fù)1.3.5對(duì)于一些網(wǎng)站我們可能會(huì)關(guān)心其所有者是誰(shuí)。比如我們已知網(wǎng)站的絡(luò)爬蟲(chóng),那么我們最好把下載速度控制得更加保守一些為有者會(huì)封禁網(wǎng)找到網(wǎng)站的所有者我們可以使用O協(xié)議查詢域名的注冊(cè)者是誰(shuí)。Pywhos7第l網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)pipinstallpyth。n-wh。下面是使用該模塊a第l網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)pipinstallpyth。n-wh。下面是使用該模塊ap.om這個(gè)域名進(jìn)行WHOIS查詢時(shí)的返回》>ip。rtwh。》>printwhois.wh。is(’appsp。t.[:、四”NSlG。。GLECOM”NS2.G。。COMNS4G。。GLE”ns4.q。。qle.com”,”ns2.q。。qle.com”,”nsl.q。。qle.GLE]”。rq”:”G。。Inc”e啤ails”:[useclaints。nit。r.com”,”dnsad皿in@q。。glecom”從結(jié)果中可以看出該域名歸屬于Goog實(shí)際上也確實(shí)如此該域名用于GoogleppEngine服務(wù)的當(dāng)我們爬取該域名時(shí)就需要分小因Google經(jīng)常會(huì)阻斷網(wǎng)絡(luò)爬蟲(chóng),盡管實(shí)際上其自身就是一個(gè)網(wǎng)絡(luò)爬蟲(chóng)業(yè)務(wù)1編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬為了抓取網(wǎng),我們首先需要下載包含有感興趣數(shù)據(jù)的網(wǎng)頁(yè)該過(guò)程一般被稱為爬?。╮awlng)爬取一個(gè)網(wǎng)站有很多種方法,而選用哪種方法更加合適則取決于目標(biāo)網(wǎng)結(jié)構(gòu)中首先會(huì)探討如何安全地下載網(wǎng)頁(yè)然后會(huì)介紹如下3種爬取網(wǎng)站的常見(jiàn)方法814編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)爬取網(wǎng)站地圖遍歷每個(gè)網(wǎng)頁(yè)的數(shù)據(jù)庫(kù)D跟蹤網(wǎng)14編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)爬取網(wǎng)站地圖遍歷每個(gè)網(wǎng)頁(yè)的數(shù)據(jù)庫(kù)D跟蹤網(wǎng)頁(yè)鏈接。下載網(wǎng)頁(yè)···1.4.要想爬取網(wǎng)頁(yè),我們首先需要將其下載下來(lái)。下面的示例腳本使用模塊下載URLllbimporturllib2defdownload(url)returnurllib2url。pen(urlread當(dāng)傳入U(xiǎn)RL參數(shù)時(shí)該函數(shù)將會(huì)下載網(wǎng)頁(yè)并返回其HTML。不過(guò),這個(gè)代碼片段存在一個(gè)問(wèn)題,即當(dāng)下載網(wǎng)頁(yè)時(shí),我們可能會(huì)遇到一些無(wú)法控制錯(cuò)誤會(huì)拋出異常,然后比如請(qǐng)求的頁(yè)面可能不存在此時(shí)urlli腳本。安全起見(jiàn),下面再給出一個(gè)更健壯的本,可以捕獲這些異常importurldefdownload(url)printD。wnl。adingurltryhtml=urllib2.urlopen(url).read()excepturllib2.URLErrorase:printDownladerrrereasnhtml=Nonereturn現(xiàn)在,當(dāng)出現(xiàn)下載錯(cuò)誤時(shí)該函數(shù)能夠捕獲到異常然后返回None1. 下載時(shí)遇到的錯(cuò)誤經(jīng)常是臨時(shí)性的,比如服務(wù)器過(guò)載時(shí)返回的ServiceUnavailable錯(cuò)誤。對(duì)于此類錯(cuò)誤,我們可以嘗試重新下載,因?yàn)檫@個(gè)服務(wù)器問(wèn)題現(xiàn)在可能己解決。不過(guò),我們不需要對(duì)所有錯(cuò)誤都嘗試9wwwsimple00wwwsimple00.om電子書(shū)分享第1網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)新下載如果服務(wù)器返回的是404otFound種錯(cuò)誤則該網(wǎng)頁(yè)目前并不存在,再次嘗試同樣的請(qǐng)求一般也不會(huì)出現(xiàn)不同的結(jié)果。teretnT完整列表,詳情可參考https://oos.ietf.org/html/rfc7231#函數(shù)發(fā)生Sxx錯(cuò)誤時(shí)重試下載即可。下面是支持重試下載功能的新本代碼defdownload(url,numretries=2printD。wnloadingurltry:html=urllib2.urlopen(url).read()excepturllib2.URLErrorase:print’Downloaderror:’,e.reasonhtml=Noneifnumretries>ifhasattr(e,’code’)and500<=e.code<600:#recursivelyretrySxxHTTPerrorsreturndownload(url,numretries-1)return現(xiàn)在,當(dāng)download函數(shù)遇到Sxx錯(cuò)誤碼時(shí)將會(huì)遞歸調(diào)用函數(shù)自身進(jìn)行重試。此外函數(shù)增加了一個(gè)參數(shù)用于設(shè)定重試下載的次數(shù)其默認(rèn)值為兩次我們?cè)谶@里限網(wǎng)頁(yè)下載的嘗試次數(shù)是因?yàn)榉?wù)器錯(cuò)誤時(shí)還沒(méi)有解決。想要測(cè)試函數(shù),可以嘗試下載http://httpsat.us/500,該網(wǎng)址會(huì)始終返回500錯(cuò)誤碼》>d。wnl。ad(’http://httpstatus500’Downl。adinghttp://httpstat.us/500D。wnloaderr。r:InternalServerErr。rD。wnl。ading:htp://httpstat.us/500Downloaderr。r:InternalServerErr。zD。wnl。ading: http://httpstat.us/500D。wnloaderr。r:InternalServerErr。r10wwwsimple00.om電子書(shū)分享wwwsimple000co機(jī)電子書(shū)分享14編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)wwwsimple000co機(jī)電子書(shū)分享14編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)從上面的返回結(jié)果可以看出,downoad函數(shù)的行為和預(yù)期一致,先嘗試下載網(wǎng)頁(yè),在接收到500錯(cuò)誤后,又進(jìn)行了兩次重試才放棄。2.設(shè)置用戶代默認(rèn)情況下,7作為用戶代理下使用Pythonurllib2.llb頁(yè)內(nèi)容其27是Python的版本號(hào)。如果能使用可辨識(shí)的用戶代理則此外,也許是因?yàn)檫@樣可以避免我們的網(wǎng)絡(luò)爬蟲(chóng)碰到一些問(wèn)題更好歷過(guò)質(zhì)量不佳的Python網(wǎng)爬蟲(chóng)造成的服器過(guò)載,一些網(wǎng)站還會(huì)封默認(rèn)的用戶代理。 比如,在使用P同il默認(rèn)用戶代理的情況下,訪問(wèn)http/wwwetupcom,前會(huì)返回如1.3所示的訪問(wèn)拒絕提示Accessη1eownerofthiswebsite()hasbannedyouraccessbasedon(?RayID:Tim臼飽mp:Mon.06心ct-1418:55:48Yo咀rIPaddres:62Reques撞edURL:www.mee燦/E.π·orreferencenumber:I0IOerID:FL33Fser-????圖.3因此,為了下載更加可靠,我們需要控制用戶代理的設(shè)定下面的代碼download函數(shù)進(jìn)行了修改,設(shè)定了一個(gè)默認(rèn)的用戶代理wsw”(即WebScrapingwithPython的首字母縮寫(xiě))defd。wnload(urluseragent=wsnumretries=2printDownloadingurlheaders={’User-agent’:useragentrequest=urllib2.Request(url,headers=headerstry:=urllib2.urlopen(request)?readexcepturllib2.URLErrorasprint’Downloaderror:’,e.reasonhtml=11wwwsimple000co機(jī)電子書(shū)分享wwwsimple000co機(jī)電子書(shū)分享第l網(wǎng)絡(luò)爬蟲(chóng)wwwsimple000co機(jī)電子書(shū)分享第l網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)ifnumretries>ifhasattr(e, ’code’)and500<=e.code<600:#retry5XXHTTPerrorsreturndownl。ad(url,user agent,numretries-return現(xiàn)在,我們擁有了一個(gè)靈活函數(shù),可以在后續(xù)示例中得到復(fù)用該函數(shù)能夠捕獲異常重試下載并設(shè)用戶代理1.網(wǎng)站地圖爬在第一個(gè)簡(jiǎn)單的爬蟲(chóng)中,我們將使用示例網(wǎng)站robots.txt文件中發(fā)現(xiàn)的網(wǎng)站地圖來(lái)下載所有網(wǎng)頁(yè)。為了解析網(wǎng)站地圖,我們將會(huì)使用一個(gè)簡(jiǎn)單正則表達(dá)式,從<loc>標(biāo)簽中提取出URL而在下一章中,我們將會(huì)介紹種更加健壯的解析方法一-css選擇器 下面是該示例爬蟲(chóng)的代碼defcrawlsitemap(url)#downloadthesitemapfilesitemap=downl。adurl#extractthesitemaplinkslinks=re.findall(’<loc>(.*?)</loc>’,sitemap#downloadeachforlinkinlinkshtml=download(link)#scrapehtml?,F(xiàn)在,運(yùn)行網(wǎng)站地圖爬蟲(chóng),從示例網(wǎng)站中下載所有國(guó)家頁(yè)面》crawl_sitemap(’http://example.webscraping.com/sitemap.xml’Dwnloading:http://example.webscraping.com/sit阻礙.mlhtp:/example.webscrapingc。/vinisn-D。loadn:D。wnl。ading:D。wnloading:http://example.webscraping.com/view/Aland-Islands-2htp://example.webscraping.com/view/Albania-3可以看出,上述運(yùn)行結(jié)果和我們的預(yù)期一致,不過(guò)正如前文所述,我們無(wú)法依靠Siemap文件提供每個(gè)網(wǎng)頁(yè)的鏈接。下一節(jié)中,我們將會(huì)介紹另-簡(jiǎn)單的爬蟲(chóng),該爬蟲(chóng)不再依賴于iemap文件12wwwsimple000co機(jī)電子書(shū)分享www.simple000co算機(jī)電子書(shū)分享l.4編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)1ID遍歷本節(jié)中,www.simple000co算機(jī)電子書(shū)分享l.4編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)1ID遍歷本節(jié)中,我們將利用網(wǎng)站結(jié)構(gòu)的弱點(diǎn),更加輕松地訪問(wèn)所有內(nèi)容。下面是一些示例國(guó)家的URL。http:IIexample.webscrapi口/view/Afghanista口-1http:IIexample.webscrapiηg.com/view/Australia http:IIexample.webscrapi口g.com/view/Brazil???可以看出,這些URL只在結(jié)尾處有所區(qū)別,包括國(guó)家名(作為頁(yè)面別名和ID。在URL中包含頁(yè)面別名是非常普遍的做法可以對(duì)搜索引擎優(yōu)化起幫助作用。一般情況下,Web服務(wù)器會(huì)忽略這個(gè)字符串,只使用D來(lái)匹配據(jù)庫(kù)中的相關(guān)記錄。加載http://example.webscrapi呵.com/view/,測(cè)試示例網(wǎng)站中的鏈接是否仍然可用。測(cè)結(jié)果如圖所示NationalCo「647,500squa『eCu「rencyName:PostalCodeFormatfa”-AF,ps,uz-TMCNIRTJPKwww.simple000co算機(jī)電子書(shū)分享1章網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)從圖中可以看出,網(wǎng)頁(yè)依然可以加載成功,也就是說(shuō)該方法是有1章網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)從圖中可以看出,網(wǎng)頁(yè)依然可以加載成功,也就是說(shuō)該方法是有用的現(xiàn)在,我們就可以忽略頁(yè)面別名,只遍歷D來(lái)下載所有國(guó)家的頁(yè)面。下面importitertoolsforpageinitertoolscou口t1url=httpexample.webscrapingcom/view/-宅d屯html=download(url)ifhtmlisNone:breakelse:#success-ca口scrapetheresultpasD設(shè)此時(shí)已到達(dá)最后一個(gè)國(guó)家的頁(yè)面不過(guò),這種實(shí)現(xiàn)方式存在一個(gè)缺陷,D到某個(gè)間隔點(diǎn),爬蟲(chóng)就會(huì)立即退出。下面是這段代碼的改進(jìn)版本中連續(xù)發(fā)生多次下載錯(cuò)誤后才會(huì)退出程序在該版#maximumnumberofconsecutivedownloaderrorsallowedmaxerrors=#currentnumberofconsecutivedownloaderrorsnumerrors=forpageiitertoolscountlurl=http/examplewebscrapingcom/view/-宅d屯html=download(url)ifhtmlisNone:#receivedannumerrors+=ifnumerrors#errortryingtodownloadthis1==maxerrorsmaximumnumber#consecutiveerrorssoexitbreakelse#success-canscrapetheresult#numerrors=wwwsimple00.om電子書(shū)分享14編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)上面代碼中實(shí)現(xiàn)的爬蟲(chóng)需要連續(xù)5wwwsimple00.om電子書(shū)分享14編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)上面代碼中實(shí)現(xiàn)的爬蟲(chóng)需要連續(xù)5次下載錯(cuò)誤才會(huì)停止遍歷,這樣就很大站D,這種方法也無(wú)法保證始終可用。比如,一些網(wǎng)站會(huì)檢查頁(yè)面別名是否滿足預(yù)期果不是返回404NtFound錯(cuò)誤而另一些網(wǎng)站則會(huì)使用連續(xù)大數(shù)作為ID,或是不使用數(shù)值作為ID,此時(shí)遍歷就難以發(fā)揮其作用了。例如Amazon使用SN作為圖書(shū)ID這種編碼包含至10位數(shù)字。使用D對(duì)Amazon的圖書(shū)進(jìn)行遍歷需要測(cè)試數(shù)十億次,因此這種方法肯定不是取該站內(nèi)容最高效的方法1鏈接爬到目前為止,我們已經(jīng)利用示例網(wǎng)站的結(jié)構(gòu)特點(diǎn)實(shí)現(xiàn)了兩個(gè)簡(jiǎn)單爬蟲(chóng),用于下載所有的國(guó)家頁(yè)只要這兩種技術(shù)可用,就應(yīng)當(dāng)使用其進(jìn)行爬因?yàn)檫@兩種方法最小化了需要下載的網(wǎng)頁(yè)數(shù)量。不過(guò),對(duì)于另一些網(wǎng)站,我們讓爬更像普,感興內(nèi)。通過(guò)跟蹤所有鏈接的方式,我們可以很容易地下載整個(gè)網(wǎng)站頁(yè)面但是,這種方法會(huì)下載大量我們并不需要的網(wǎng)頁(yè)。例如,我們想要從一個(gè)在線論壇中抓取用戶賬號(hào)詳情頁(yè),那么此時(shí)我們只需要下載賬號(hào)頁(yè),而不需要下載討論貼的頁(yè)面。本節(jié)中的鏈接爬蟲(chóng)將使用正則表達(dá)式來(lái)確定需要下載哪些頁(yè)面。下面是這段代碼的初始版本importdeflink_crawler(seed_url,link_regex)”””CrawlfromthegivenseedURLfollowinglinksmatchedbylinkregex]。)-15wwwsimple00.om電子書(shū)分享eeaueelonesueww rqCeulewuweu4wwwsimple000.c算m機(jī)電子書(shū)分第1章網(wǎng)絡(luò)wwwsimple000.c算m機(jī)電子書(shū)分第1章網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)#filterforlinksmatchingourregularexpressionforlinkingetlinks(html):ifre.match(linkregexlikcrawl_queue.append(link)defgetlinks(html)Retur口alistoflinksfrom#aregularexpressionextractalllinksfromthewebpageregex=pile(<a>]+href=[\]()[\re.#listofalllinksfromthewebpageretur口webpageregex.findall(html)’只需要調(diào)用licrawler函數(shù),并傳入兩個(gè)參數(shù)要運(yùn)行這段代碼要爬取的網(wǎng)站URL和用于跟蹤鏈接的正則表達(dá)式。對(duì)于示例網(wǎng)我們想爬取的是國(guó)家列表索引頁(yè)和國(guó)家頁(yè)面。其中,索引頁(yè)鏈接格式如下?http:IIxaple.webscraping.com/x/1http:IIxaple.webscraping.com土口dex/?國(guó)家頁(yè)鏈接格式如下http:I/xaple.webscraping.com//Afhaitan-httpI/examplewebscrapingcomview/Aland-Is口ds??因此,我們可以用/(index[view)/這個(gè)簡(jiǎn)單的正則表達(dá)式來(lái)匹配這兩類網(wǎng)頁(yè) 當(dāng)爬蟲(chóng)使用這些輸入?yún)?shù)運(yùn)行時(shí)會(huì)發(fā)生什么呢?你會(huì)發(fā)現(xiàn)我們得到如下的下載錯(cuò)誤》>linkcrawler(http/’,’I(indexIview)’)Downloading:http://Downloading:/index/1Traceback(mostrecentcalllast)ValueError:unknownurltypeIidex/1wwwsimple000.c算m機(jī)電子書(shū)分www.simple000co算機(jī)電子書(shū)分享網(wǎng).4編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)可看出,出在下載/ndex/1時(shí),該鏈接只有的路徑部分正在瀏覽哪個(gè)網(wǎng)頁(yè),所以在瀏覽器瀏覽時(shí),相對(duì)鏈接是能夠正常工作的但是llib2無(wú)法獲知上下文的為了讓需要www.simple000co算機(jī)電子書(shū)分享網(wǎng).4編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)可看出,出在下載/ndex/1時(shí),該鏈接只有的路徑部分正在瀏覽哪個(gè)網(wǎng)頁(yè),所以在瀏覽器瀏覽時(shí),相對(duì)鏈接是能夠正常工作的但是llib2無(wú)法獲知上下文的為了讓需要將鏈接轉(zhuǎn)換為絕對(duì)鏈接的形式,以便包含定位2能夠定位網(wǎng)頁(yè),我頁(yè)的所有細(xì)節(jié)。如你Pyton中確實(shí)有用來(lái)實(shí)現(xiàn)一功能的模塊該模塊稱為urparse面是licraler的改進(jìn)版本使用urlparse模塊來(lái)創(chuàng)建絕對(duì)路徑importurlparsedeflink_crawler(seedurl,linkregex)”””CrawlfromthegivenseedURLfollowinglinksmatchedbylink---h(huán)tml=download(urlforlinkingetlinks(html)ifre.match(link_regex,link)lik=urlparseurljoinseedurllink)crawl_queue.append(link)當(dāng)你運(yùn)行這段代碼時(shí),會(huì)發(fā)現(xiàn)雖然網(wǎng)頁(yè)下載沒(méi)有出現(xiàn)錯(cuò)誤,但是同樣的點(diǎn)總是會(huì)被不斷下載到這是因?yàn)檫@些地點(diǎn)相互之間存在鏈接。比如,澳大利亞鏈接到了南極洲,而南極洲也存在到澳大利亞的鏈接,此時(shí)爬蟲(chóng)就會(huì)要想避免重復(fù)爬取相同的鏈接它們之間不斷循環(huán)下去我們需現(xiàn)URL的功能,可以避免重復(fù)下載rwler函數(shù),己具備存儲(chǔ)己deflinkcrawler(seedurl,linkregex)crawlqueue=[seedurl#keeptrackwhichURL’shaveseenbefore)口-)-)口www.simple000co算機(jī)電子書(shū)分享網(wǎng)14sppleueetaeuueeqoeSzurLeWoErereWacC1414eulErhcwewwwsimple00om電子書(shū)分享第wwwsimple00om電子書(shū)分享第l網(wǎng)絡(luò)爬蟲(chóng)#checkiflinkmatchesexpectedregexifre.match(linkregex,link):#formabsolutelinklink=urlparseurljoin(seed_url,link)#checkifhavealreadyseenthislinkiflinknotiseenseen.crawlqueue.append(l當(dāng)運(yùn)行該腳本時(shí),它會(huì)爬取所有地點(diǎn),并且能夠如期停止。最終,我們得高級(jí)功現(xiàn)在,讓我們?yōu)殒溄优老x(chóng)添加一些功能,使其在爬取其他網(wǎng)站時(shí)更用。解robot.txt首先,我們需要解析robots.txt文件,以避免下載禁止爬取的URL用Python自帶的robotparser模塊,就可以輕松完成這項(xiàng)工作,如下的代碼所示》>imp。rtz。b?!罚緍p=r。b。tparserRob。tFileParser()》>rp.set_urlhttp://ex四1plewebscraping.comrob。ts.txt’》>rpread()》》》url=’=’BadCrawlerrp.can_fetch(use?二agent url》》=G。。dCrawlerrpcan_fetch(user_agentlft函數(shù)確指定的用戶代理是否允許訪問(wèn)網(wǎng)頁(yè)在本例中當(dāng)用戶代理設(shè)為’BadCrawler’時(shí),robotparser模塊會(huì)返回結(jié)果表明無(wú)法獲取網(wǎng)頁(yè)這和示例網(wǎng)robotstxt的定義一樣。18wwwsimple00om電子書(shū)分享wwwsimple00om電子書(shū)分享14編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)為了將該功能wwwsimple00om電子書(shū)分享14編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)為了將該功能集成到爬蟲(chóng)中,我們需要在crawl循環(huán)中添加該檢查。whilecrawlqueuecrawl_queuep。purl#checkurlpassesrobots.txtrestrictionsifrp.can_fetch(user_agent,url):elseprintBl。ckedbyrobotstx支持代有時(shí)我們需要使用代理訪問(wèn)某個(gè)網(wǎng)比如,Netflix屏蔽了美國(guó)以外大多數(shù)國(guó)家。使用ib支持代理并沒(méi)有想象中那么容易(可以嘗試使用更友好PythonHTTP模塊requests來(lái)實(shí)現(xiàn)該其文檔地址為http//)下面是使用ib支持代理的代碼proxyopener=urllib2.build_opener(pr。xyparams={urlparse.urlparse(url).scheme:proxy}。peneraddhandlerurllib2ProxyHandlerpr。xy_paramsresponse=openerpenrequestdefdownload(url,user_agent=’wswp’,proxy=None,num_retries=2)print’Downloading:’,urlheaders={’User-agent’user_agent}request=urllib2.Request(url,headers=headersopener=urllib2build一。penerifproxyproxyparams{urlparse.urlparse(url).scheme:proxy}openeraddhandlerurllib2Pr。xyHandler(proxyparams))tryhtml=openerpenrequestreadexcepturllib2URLErrorase:printDownladerrorereason19wwwsimple00om電子書(shū)分享算機(jī)電子書(shū)分享網(wǎng)1章網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)介html=ifnumretries算機(jī)電子書(shū)分享網(wǎng)1章網(wǎng)絡(luò)爬蟲(chóng)簡(jiǎn)介html=ifnumretries>ifhasattr(e,’code’)and500<=e.code<#retrySXXHTTPerrorshtml=download(url,useragent,proxy,numretries-1)return下載F險(xiǎn)。為了降低這些風(fēng)險(xiǎn),我們可以在兩次下載之間添加延時(shí),從而對(duì)爬蟲(chóng)速下面是實(shí)現(xiàn)了該功能類的代碼classThrottle”””Addadelaybetweendownloadstothesamedef一_init一_(selfdelay)#amountofdelaybetweendownloadsforeachdomainself.delay=delay#timestampofwhenadomainwaslastaccess=self.{}defwait(self,url)domain=urlparseurlparseurl).netl。last_accessed=selfd。mainsget(domainifselfdelay>0andlastaccessedisn。tNonesleepsecs=self.delay-(datetime.datetime.now()lastaccessed).secondsifsleepsecs>#domainhasbeenaccessedrecently#soneedtosleeptime.sleep(sleepsecs)#updatethelastaccessedtimeselfd。mainsd。main=datetimedatetime-Trtte類記錄了每個(gè)域名上訪問(wèn)的時(shí)間,如果當(dāng)前時(shí)間距離上訪問(wèn)時(shí)間小指定延時(shí),則執(zhí)行睡眠操作。我們可以在每次下載之Throttle對(duì)爬蟲(chóng)進(jìn)行限速算機(jī)電子書(shū)分享網(wǎng)算機(jī)電子書(shū)分享網(wǎng)1編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)thr。ttle=Throttledelay)throttle.wait(urlresult=download(url,headers,proxy=proxy,numretries=numretries)避免爬蟲(chóng)陷目前,我們的爬蟲(chóng)會(huì)跟蹤所算機(jī)電子書(shū)分享網(wǎng)1編寫(xiě)第一個(gè)網(wǎng)絡(luò)爬蟲(chóng)thr。ttle=Throttledelay)throttle.wait(urlresult=download(url,headers,proxy=proxy,numretries=numretries)避免爬蟲(chóng)陷目前,我們的爬蟲(chóng)會(huì)跟蹤所有之前沒(méi)有訪問(wèn)過(guò)的鏈接。但是,一些網(wǎng)站會(huì)動(dòng)態(tài)生成頁(yè)面內(nèi)容,這樣就會(huì)出現(xiàn)無(wú)限多的網(wǎng)頁(yè)比如網(wǎng)有一個(gè)在線日歷功能,提供了可以訪問(wèn)下個(gè)月和下一年的鏈接,那么下個(gè)月的頁(yè)面中同樣會(huì)包含訪問(wèn)再下個(gè)月的鏈接,這樣頁(yè)面就會(huì)無(wú)止境地鏈接下去。這種情況被想要避免陷入爬蟲(chóng)陷阱,一個(gè)簡(jiǎn)單的方法是記錄到達(dá)當(dāng)前網(wǎng)頁(yè)經(jīng)過(guò)了多少個(gè)鏈接,也就是深度。當(dāng)?shù)竭_(dá)最大深度時(shí),爬蟲(chóng)就不再向隊(duì)列中添加該網(wǎng)頁(yè)中的鏈接了。要實(shí)現(xiàn)這一功能,我們需要修改seen變量。該變量原先只錄訪問(wèn)過(guò)的網(wǎng)頁(yè)鏈接,現(xiàn)在修改為一個(gè)字典,增加了頁(yè)面深度的記錄deflinkcrawler(...,maxdepth=2):maxdepth=2口=電=--、。iflinknotinseen『+()該功能,只需將max_depth設(shè)為一個(gè)負(fù)數(shù)即可,此時(shí)當(dāng)前深度永遠(yuǎn)不會(huì)與最終版這個(gè)高級(jí)鏈接爬蟲(chóng)的完整源代碼可以在https:bitbucket.or/li_w3算機(jī)電子書(shū)分享網(wǎng)1htpeeknupnilLnenersneeeshefd第1章網(wǎng)絡(luò)爬蟲(chóng)試這段代碼,我們可以將用戶代理設(shè)置為BCrw也就是章第1章網(wǎng)絡(luò)爬蟲(chóng)試這段代碼,我們可以將用戶代理設(shè)置為BCrw也就是章前文從下面的運(yùn)行結(jié)果中可以述的被robts.屏蔽了的那個(gè)用戶代理爬蟲(chóng)果然被屏蔽了,代碼啟動(dòng)后馬上就會(huì)結(jié)束》》=’http://ex四iplewebscrapingc。lirgex=’/(ivie)》>link_crawler(seed_urlliregexuser_agent=’BadCrawler’Blockedbyrobots.txt:http://example.webscraping.現(xiàn)在,讓我們使用默認(rèn)的用戶代理,并將最大深度設(shè)置為1,這樣只有主》>li」crawlerseed_urlliregexD。wnl。ading:http/examplewebscrapingcomindexDownl。adinghttp/examplewebscrapingc。m/index/lDownl。ading:D。wnl。ading:D。wnloading:Downloading:Downloading:D。wnloading:D。wnloading:D。wnlading:http://example.webscraping.cov-and-Barbuda-10http://exa皿l.webscraping.c。m/view/Antarctica-9http://example.webscraping.c。皿/iewuilla-ht://example.webscraping.com/view/Ang。la7http://example.webscraping.com/view/Andorra-http://ex皿1ple.webscraping.c。m/view/陽(yáng).erican-Sa5http://ex四ple.w,由scraping.com/view/Algeria-4http://example.webscraping.com/view/Albania-http:/examplewebscrapingcom/view/Aland-工sl2http://example.webscraping.c。m/view/Afghanistan-1和預(yù)期一樣,爬蟲(chóng)在下載完國(guó)家列表的第一頁(yè)之后就停止了1.本章小結(jié)本章介紹了網(wǎng)絡(luò)爬蟲(chóng),然后開(kāi)發(fā)了一個(gè)能夠在后章節(jié)中用的成熟蟲(chóng)。此外,我們還介紹了一些外部工具和模塊的使用方法,用于了解網(wǎng)站網(wǎng)站地圖爬取延時(shí)以及各種爬取策略用戶代理我們將討論如何從己爬取到的網(wǎng)頁(yè)中獲取數(shù)據(jù)數(shù)據(jù)抓在上一章中,我們構(gòu)建了一數(shù)據(jù)抓在上一章中,我們構(gòu)建了一個(gè)爬蟲(chóng),可以通過(guò)跟蹤鏈接的方式下載我們所需的網(wǎng)頁(yè)。雖然這個(gè)例子很有意思, 卻不夠?qū)嵱茫?因?yàn)榕老x(chóng)在下載網(wǎng)頁(yè)之后又將結(jié)果丟棄掉了。現(xiàn)在,我們需要讓這個(gè)爬蟲(chóng)從每個(gè)網(wǎng)頁(yè)中抽取一些數(shù)據(jù)然后實(shí)現(xiàn)某些事情這種做法也被稱為抓取 首先,我們會(huì)介紹一FirebugLite的瀏覽器擴(kuò)展,用于檢查網(wǎng)頁(yè)內(nèi)容,如果你有一些網(wǎng)絡(luò)開(kāi)發(fā)背景的話,可能己經(jīng)對(duì)該擴(kuò)展十分熟悉了。然后,BeautiSoup們會(huì)介紹三種抽取網(wǎng)頁(yè)數(shù)據(jù)的方法,分別是正則表達(dá)式lxml。最后,我們將對(duì)比這數(shù)據(jù)抓取方法2.分析網(wǎng)想要了解一個(gè)網(wǎng)頁(yè)的結(jié)構(gòu)如何 可以使用查看源代碼的方法。在大多數(shù)覽器中,都可以在頁(yè)面上右鍵單擊選擇源代碼,如圖21所示pagesource選工頁(yè),獲取網(wǎng)頁(yè)我們可以在H刊伍的下述代碼中找到我們感興趣的數(shù)據(jù)<table><trid=”places_national_flag_row”><tdclass=”w2p_fl”><labefor=”places_national_flag2id=”placesnationallabel”>National</label></td><tdclass=”w2pfw”><imgsrc=”/ <trid=”places口eighboursfor=”placesid=”placesrow"><tdclass=”w2plabel”>Neighbours:' 2id=”placesnationallabel”>National</label></td><tdclass=”w2pfw”><imgsrc=”/ <trid=”places口eighboursfor=”placesid=”placesrow"><tdclass=”w2plabel”>Neighbours:' class=”w2pLc;i.:ir1器244,820squarekilorne甘NationalCurrencyC創(chuàng)eCurrencyNamePostalCodeFo『SaveTranslatetons因ctw1ll1Firebug?en-GB,cy-GIuser-AgentInspect對(duì)于瀏覽器解析而言,缺失空白符和格式并無(wú)大礙,但在我們閱讀時(shí)則會(huì)造一定困難。要想更好地理解該表格,我們將使用FirebugLite擴(kuò)展。該擴(kuò)展適用于所有瀏覽器,我們可以通過(guò)https://getfirebugcomfirebuglite頁(yè)面獲取到該擴(kuò)展。如果愿意的話,F(xiàn)irefox用戶可以安裝完整版的擴(kuò)展,不過(guò)Lite版本己經(jīng)包含了我們?cè)诒菊潞偷?章中所用到的功能Firebug安裝完成后可以右鍵單擊我們?cè)谧ト≈懈信d擴(kuò)展,不過(guò)Lite版本己經(jīng)包含了我們?cè)诒菊潞偷?章中所用到的功能Firebug安裝完成后可以右鍵單擊我們?cè)谧ト≈懈信d趣的網(wǎng)頁(yè)部分e然后在菜單中選擇Inspect如圖2.2所示Cu廳encyCurrencySaveTranslatetoViewpageVi四'/pageNeighbou「Inspect并顯示選中元素周此時(shí),瀏覽器就會(huì)打開(kāi)如圖2.3所示的Firebug面板,圍的HTML層次結(jié)構(gòu)。如圖2.3所示 當(dāng)選擇國(guó)家面積這一屬性時(shí) 我們可以從Firebug面板清晰地看到,該值包含在class為w2pfw的td>元素中,而<td>元素又ID為places arearowtr元素的子元素。現(xiàn)在我們就獲取到需要抓取的面積數(shù)據(jù)的所有信息了e計(jì)算機(jī)電子書(shū)第2數(shù)據(jù)抓取Script臼bodydata計(jì)算機(jī)電子書(shū)第2數(shù)據(jù)抓取Script臼bodydatady-mini;"sectionid=可nain"class=陰陽(yáng)inrow與日divclass=·pn旦、國(guó)<fomaction=”?!眅nctype=飛ultipart/fonn-data”mεthod=’'post”〉<tridplaces_nationaflag_rowtrid="lacsa_><tdclass="1"2p_fl”<td三種網(wǎng)頁(yè)抓取方現(xiàn)在我們已經(jīng)了解了該網(wǎng)頁(yè)的結(jié)構(gòu),下面將要介紹三種抓取其中數(shù)據(jù)的方法。首先是正則表達(dá)式,然后是流行的BeautifulSoup模塊,最后是強(qiáng)的lxml模塊正則表達(dá)式還不熟悉,或是需要一些提示時(shí)httpsdocs.pytho日org/2/howtoregexhtml獲得完整介紹首先需要嘗試匹配<td>元素當(dāng)我們使用正則表達(dá)式抓取面積數(shù)據(jù)時(shí),的內(nèi)容,如下所示。》〉工mport》>url=’httpelewebscrapi口gcom/view/Un工-Kingdom239》>html=download(url>>>re.findall(’<tdclass=”w2pw”(.*?)</td>’[’<imgsrc=”/places/stat工c/images/flags/gb.pnghtml/〉’計(jì)算機(jī)電子書(shū)2.2三種網(wǎng)頁(yè)抓取方法’244,820squarekilometres’’62.2三種網(wǎng)頁(yè)抓取方法’244,820squarekilometres’’62,348,7’,’G’UnitedKingd。m'L。ndonahref=letinent/EUEU/a>’,’.uk’,’GBP’,’Pound’,’@#@@I@##@@I自由##@日I@@##@@I@@@@I@@#自@@IGIRO"(([AZd2}[AZ2)I(AZ\d3}[AZ]2)([A-Z{2}\\d{2[A-Z]{2})I([A-Z]{2}\\d{3[-Z]{2}IAZd[AZdA』Z]2I([A-Z]{2}\\d[A-Z]\\d[A-Z]{2})I(GIROA))$’’en-GB,cy-GB,gd’<divahref=isoEIEadiv從上述結(jié)果中可以看出,多個(gè)國(guó)家屬性都使用了<tdclassw2fw標(biāo)簽。要想分離出面積屬性,我們可以只選擇其中的第二個(gè)元素,如下所示[lre.findall(’<tdclass=”w2pfw”>(.??)</td>html244820squarekilmetres雖然現(xiàn)在可以使用這個(gè)方案,但是如果網(wǎng)頁(yè)發(fā)生變化,該方案很可能就會(huì)失效。比如表格發(fā)生了變化,去除了第二行中的國(guó)土面積數(shù)據(jù)。如果我們只在現(xiàn)在抓取數(shù)據(jù),就可以忽略這種未來(lái)可能發(fā)生的變化。但是,如果我們希望未來(lái)還能再次抓取該數(shù)據(jù),就需要給出更加健壯的解決方案,從而盡可能避免這種布局變化所帶來(lái)的影響。想要該正則表達(dá)式更加健壯,我們可以將其父元素tr>也加入進(jìn)來(lái)。由于該元素具有ID屬性,所以應(yīng)該是唯一的》refindall(<trid=placesareaclass=”w2pfl”><labelfor=”placesareai”placesarealabel”>Area:</label><class=w2pfw()td,html[244820squarekilometreswwwsimple000om機(jī)電子書(shū)分wwwsimple000om機(jī)電子書(shū)分享網(wǎng)2章數(shù)據(jù)抓取這個(gè)迭代版本看起來(lái)更好一些,但是網(wǎng)頁(yè)更新還有很多其他方式,同樣可以讓該正則表達(dá)式無(wú)法滿足。比如,將雙引號(hào)變?yōu)閱我?hào),<td>標(biāo)簽之間添加多余的空格,或是變更area label等。下面是嘗試支持這些可能性的改進(jìn)版本》>refindall(<trid="places r。w>.??<td\sclass=[\’]w2pfw[\’]〉(</td’,html[’244,820squarekilometres’雖然該正則表達(dá)式更容易適應(yīng)未來(lái)變化,但又存在難以構(gòu)造、可讀性差的問(wèn)題 此外 還有一些微小的布局變化也會(huì)使該正則表達(dá)式無(wú)法滿足在td>標(biāo)簽里添加title屬性。比如從本例中可以看出,正則表達(dá)式為我們提供了抓取數(shù)據(jù)的快捷方式,但該方法過(guò)于脆弱,容易在網(wǎng)頁(yè)更新后出現(xiàn)問(wèn)題。幸好,還有一些更好的解決方案,我們會(huì)在接下來(lái)的小節(jié)中繼續(xù)介紹。2.2.2BeautifulBeautifulSoup是一個(gè)非常流行Python模塊。該模塊可以解析網(wǎng)提供定位內(nèi)容的便捷接口。如果你還沒(méi)有安裝該模塊,可以使用下面的命令安裝其最新版本pipinstallils。BeautifulSoup的第一步是將己下載的內(nèi)容解析為soup文檔使由于大多數(shù)網(wǎng)頁(yè)都不具備良好的HTML格式,因此BeautifulSoup需要對(duì)其實(shí)際格式進(jìn)行確定。例如,在下面這個(gè)簡(jiǎn)單網(wǎng)頁(yè)的列表中,存在屬性值兩側(cè)引號(hào)缺失和標(biāo)簽未閉含的問(wèn)題<ulclass=country><li>Area<li>P。pulation</wwwsimple000om機(jī)電子書(shū)分享網(wǎng)算機(jī)電子書(shū)分享網(wǎng)2.2方法如果Population列表項(xiàng)被解析為Area列表項(xiàng)的子元素,而不是并的兩算機(jī)電子書(shū)分享網(wǎng)2.2方法如果Population列表項(xiàng)被解析為Area列表項(xiàng)的子元素,而不是并的兩個(gè)列表項(xiàng)的話,我們?cè)谧トr(shí)就會(huì)得到錯(cuò)誤的結(jié)果。下面讓我們看一BeautifulSoup是如何處理的①。》>frombs4importBeautifulSoup》》》》》br。kenhtml=<ulclass=country><li>Areali>Populationul#parsethesoup=BeautifulSoup(broken_html,’html.parser’fixedhtml=soup.prettifyprintfixed<ulclass=country<li>Area</工<li>Population</li></ul></body></Soup從上面的執(zhí)行結(jié)果中可以看出Beauti能夠正確解析缺失的引號(hào)并閉合標(biāo)簽,此外還添加了<html>和<body>標(biāo)簽使其成為完整findall()方法來(lái)定位我們需要的HTML文檔?,F(xiàn)在可以使用元素了find()》>ul=soupfind(ul’,attrs={class’coutry})ulfind(li)#returnsjustthefirst<li>Area</li>ulfindall(l)#returnsallmatche[¢除了…倒叫……檔li>ArealiliPopulatili其網(wǎng)址為:httpwww.crummycomsoftwareBeautifu1Soup/bs4doc/①譯者注2此處使用的是時(shí)也on內(nèi)置庫(kù),由于不同版本的容錯(cuò)能力有所區(qū)別,讀者在實(shí)踐中可能無(wú)法得到正確結(jié)果。相關(guān)內(nèi)容可參考zhttpswwwcrummy.comsoftware/Beautifu1Soup/bs4doc/installingaparser.算機(jī)電子書(shū)分享網(wǎng)2章數(shù)據(jù)抓取下面是使用該方法抽取示例國(guó)家面積數(shù)據(jù)的完整代碼》》frombs4importBeautifulSoup2章數(shù)據(jù)抓取下面是使用該方法抽取示例國(guó)家面積數(shù)據(jù)的完整代碼》》frombs4importBeautifulSoupurl=’http:///places/view/UnitedKingdom239’html=download(urlsoup=BeautifulSoup(html#1catethearea》》》》》》trtdareasoup.find(attrs={’id’:’places_area_row’})tr.find(attrs={’class’:’w2p_f’))#locate=td.text#extractthetextfromthisarea》>print244,820squarekilometres這段代碼雖然比正則表達(dá)式的代碼更加復(fù)雜,但更容易構(gòu)造和理解。而且,像多余的空格和標(biāo)簽屬性這種布局上的小變化,我們也無(wú)須再擔(dān)心了2.2.3Lxml是基于libxml2這一XML解析庫(kù)的Python封裝。該模塊使用語(yǔ)言編寫(xiě),解析速度比BeautifulSoup更快,不過(guò)安裝過(guò)程也更為復(fù)雜。最的安裝說(shuō)明可以參考http://Lxmlde/installationhtml和Soup一樣,使lxml模塊的第一步也是將有可能不合法的HTML解析為統(tǒng)一格式。下面是使用該模塊解析同一個(gè)不完整HTML的例子》>importlxml》>brokenhtml=<ulclass=country><li>Area<li>Population<ul》》》tree=lxml.html.fromstring(broken_html)#parsethefixedhtml=lxml.html.tostring(tree,pretty_print=True)printfixed_htmlclass=”country"><li>Area</li><li>Population</li></lxml也可以正確解析屬性兩側(cè)缺失的引號(hào),并閉合標(biāo)簽不同樣地,該模塊沒(méi)有額外添加<html>和<body>標(biāo)簽www.simple000co算機(jī)電子書(shū)分享網(wǎng)2.2三種網(wǎng)頁(yè)抓取方法解析完輸入內(nèi)容之后, 進(jìn)入選擇元www.s

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論