很多人在搜索機(jī)票,發(fā)現(xiàn)機(jī)票價(jià)格在白天波動(dòng)。因此試圖找出最佳的購(gòu)票時(shí)間,但網(wǎng)上沒(méi)有任何幫助。程序員就會(huì)構(gòu)建了一個(gè)小程序來(lái)自動(dòng)從Web收集數(shù)據(jù)所謂的刮板程序。它在預(yù)定日期提取了特定航班目的地的信息,并在價(jià)格降低時(shí)通知到使用的人。Web抓取是一種用于通過(guò)自動(dòng)化過(guò)程從網(wǎng)站提取數(shù)據(jù)的技術(shù)。從這種Web抓取的經(jīng)驗(yàn)中學(xué)到了很多東西,下面是詳細(xì)介紹。
有興趣了解與網(wǎng)頁(yè)抓取相關(guān)的常見(jiàn)設(shè)計(jì)模式,陷阱和規(guī)則的人員使用。該ariticle存在一些使用案例和典型的集合的問(wèn)題,比如如何不被檢測(cè)到,DOS和注意事項(xiàng),以及如何加快(并行)的刮刀。
一切都會(huì)伴隨有python代碼段,因此您可以立即開(kāi)始。本文檔還將介紹一些有用的python軟件包。
用例
您想抓取數(shù)據(jù)的原因和用例有很多。讓我列出其中一些:
· 刮擦電子零售商的頁(yè)面以發(fā)現(xiàn)您要購(gòu)買(mǎi)的某些衣服是否打折;
· 通過(guò)抓取頁(yè)面來(lái)比較幾個(gè)服裝品牌的價(jià)格;
· 機(jī)票價(jià)格白天可能會(huì)有所不同。價(jià)格降低后,一個(gè)人可能會(huì)爬行旅行網(wǎng)站并驚慌;
· 分析行動(dòng)網(wǎng)站以回答以下問(wèn)題:起始出價(jià)應(yīng)低還是高以吸引更多競(jìng)標(biāo)者,或者更長(zhǎng)的拍賣(mài)與更高的最終出價(jià)相關(guān)。
講解
本教程的結(jié)構(gòu):
1. 可用包裝;
2. 基本代碼;
3. 陷阱;
4. 該做什么和不該做什么;
5. 加速—并行化。
在我們開(kāi)始之前:對(duì)服務(wù)器要好一些;您不想使網(wǎng)站崩潰。
1.可用的軟件包和工具
對(duì)于Web抓取,沒(méi)有通用的解決方案,因?yàn)樵诿總€(gè)網(wǎng)站上存儲(chǔ)數(shù)據(jù)的方式通常是特定于該網(wǎng)站的。實(shí)際上,如果您要抓取數(shù)據(jù),則需要了解網(wǎng)站的結(jié)構(gòu)并構(gòu)建自己的解決方案或使用高度可定制的解決方案。
但是,您不需要重新發(fā)明輪子:有許多軟件包可以為您發(fā)揮最大的作用。根據(jù)您的編程技能和預(yù)期的用例,您可能會(huì)發(fā)現(xiàn)或多或少有用的不同軟件包。
1.1檢查選項(xiàng)
大多數(shù)時(shí)候,您會(huì)發(fā)現(xiàn)自己在檢查HTML網(wǎng)站。您可以使用Bowser的“檢查”選項(xiàng)輕松完成此操作。
網(wǎng)站上保存著我的名字,頭像和描述的部分被稱(chēng)為hero hero--profile u-flexTOP。名為我的類(lèi)被調(diào)用ui-h2 hero-title,并且描述包含在類(lèi)中ui-body hero-description。
1.2cra
有一個(gè)名為Scrapy的獨(dú)立的隨時(shí)可用的數(shù)據(jù)提取框架。除了提取HTML之外,該程序包還提供許多功能,例如以格式導(dǎo)出數(shù)據(jù),記錄日志等。它還可以高度自定義:在不同的進(jìn)程上運(yùn)行不同的Spider,禁用Cookies1并設(shè)置下載延遲2。它也可以用于使用API提取數(shù)據(jù)。但是,對(duì)于新程序員來(lái)說(shuō),學(xué)習(xí)曲線(xiàn)并不順利:您需要閱讀教程和示例才能上手。
· 有些網(wǎng)站使用Cookie來(lái)識(shí)別機(jī)器人。
· 由于大量抓取請(qǐng)求,網(wǎng)站可能超載。
對(duì)于我的用例,它太“開(kāi)箱即用”:我只想從所有頁(yè)面中提取鏈接,訪(fǎng)問(wèn)每個(gè)鏈接并從中提取信息。
1.3帶有請(qǐng)求的BeautifulSoup
BeautifulSoup是一個(gè)庫(kù),可讓您以?xún)?yōu)美的方式解析HTML源代碼。同時(shí),您需要一個(gè)請(qǐng)求庫(kù),該庫(kù)將獲取URL的內(nèi)容。但是,您應(yīng)該注意所有其他事項(xiàng),例如錯(cuò)誤處理,如何導(dǎo)出數(shù)據(jù),如何并行化Web抓取工具等。
我選擇BeautifulSoup是因?yàn)樗鼤?huì)迫使我找出Scrapy自己處理的許多內(nèi)容,并希望可以幫助我從錯(cuò)誤中更快地學(xué)習(xí)。
2.基本代碼
開(kāi)始抓取網(wǎng)站非常簡(jiǎn)單。大多數(shù)時(shí)候,您會(huì)發(fā)現(xiàn)自己在檢查網(wǎng)站的HTML以訪(fǎng)問(wèn)所需的類(lèi)和ID。假設(shè)我們具有以下html結(jié)構(gòu),并且我們希望提取main_price元素。注意:discounted_price元素是可選的。
<body>
<div id =“ listings_prices”>
<div class =“ item”>
<li class =“ item_name”>手表</ li>
<div class =“ main_price”>價(jià)格:66.68美元</ div>
<div class =“折扣價(jià)格:46.68美元</ div>
</ div>
<div class =” item“>
<li class =” item_name“> Watch2 </ li>
<div class =” main_price“>價(jià)格:56.68美元< / div>
</ div>
</ div>
</ body>
基本代碼是導(dǎo)入庫(kù),執(zhí)行請(qǐng)求,解析html,然后找到class main_price。
有可能出現(xiàn)class main_price在網(wǎng)站的其他部分。為了避免class main_price從網(wǎng)頁(yè)的任何其他部分提取不必要的內(nèi)容,我們可以先解決id listings_prices,然后再使用查找所有元素class main_price。
3.陷阱
3.1檢查robots.txt
網(wǎng)站的抓取規(guī)則可在robots.txt文件中找到。您可以通過(guò)在主域名。例如,之后編寫(xiě)robots.txt來(lái)找到它。這些規(guī)則確定不允許自動(dòng)提取網(wǎng)站的哪些部分,或者允許漫游器多久請(qǐng)求一次頁(yè)面。大多數(shù)人都不在乎它,但是即使您不打算遵守這些規(guī)則,也要盡量保持尊重并至少看一下這些規(guī)則。
3.2 HTML可能是邪惡的
HTML標(biāo)記可以包含id,class或兩者。HTML id指定唯一的ID,HTML類(lèi)是唯一的。類(lèi)名或元素的更改可能會(huì)破壞您的代碼或提供錯(cuò)誤的結(jié)果。
有兩種方法可以避免它,或者至少要對(duì)其進(jìn)行提醒:
· 使用特定的id而不是class因?yàn)樗惶赡鼙桓模?/p>
· 檢查元素是否返回 None。
但是,由于某些字段是可選的(例如discounted_price在我們的HTML示例中),因此相應(yīng)的元素不會(huì)出現(xiàn)在每個(gè)列表中。在這種情況下,您可以計(jì)算此特定元素返回“無(wú)”的次數(shù)占列表數(shù)量的百分比。如果是100%,則可能要檢查元素名稱(chēng)是否已更改。
3.3用戶(hù)代理欺騙
每次您訪(fǎng)問(wèn)網(wǎng)站時(shí),它都會(huì)通過(guò)用戶(hù)代理獲取瀏覽器信息。除非您提供用戶(hù)代理,否則某些網(wǎng)站不會(huì)向您顯示任何內(nèi)容。另外,某些站點(diǎn)向不同的瀏覽器提供不同的內(nèi)容。網(wǎng)站不想阻止真正的用戶(hù),但是如果您使用相同的用戶(hù)代理每秒發(fā)送200個(gè)請(qǐng)求,您就會(huì)感到可疑。一種解決方法是要么生成幾乎隨機(jī)用戶(hù)代理,要么自行設(shè)置。
3.4超時(shí)請(qǐng)求
默認(rèn)情況下,Request將無(wú)限期地等待響應(yīng)。因此,建議設(shè)置超時(shí)參數(shù)。
3.5我被封鎖了嗎
頻繁出現(xiàn)狀態(tài)代碼,例如404(未找到),403(禁止),408(請(qǐng)求超時(shí)),可能表明您已被阻止。您可能需要檢查這些錯(cuò)誤代碼,然后進(jìn)行相應(yīng)處理。
另外,準(zhǔn)備處理請(qǐng)求中的異常。
3.6 IP輪換
即使您將用戶(hù)代理隨機(jī)化,所有請(qǐng)求都將來(lái)自同一IP地址。這聽(tīng)起來(lái)并不異常,因?yàn)閳D書(shū)館,大學(xué)以及公司只有幾個(gè)IP地址。但是,如果通常有多個(gè)請(qǐng)求來(lái)自單個(gè)IP地址,則服務(wù)器可以檢測(cè)到它。使用共享代理,VPN或TOR可以幫助您成為鬼魂。
通過(guò)使用共享代理,網(wǎng)站將看到代理服務(wù)器的IP地址,而不是您的IP地址。VPN將您連接到另一個(gè)網(wǎng)絡(luò),并且VPN提供商的IP地址將發(fā)送到該網(wǎng)站。
3.7蜜罐
蜜罐是檢測(cè)爬蟲(chóng)或刮板的手段。
這些可以是用戶(hù)看不見(jiàn)的“隱藏”鏈接,但可以由刮板/蜘蛛提取。此類(lèi)鏈接的CSS樣式設(shè)置為display:none,可以通過(guò)具有背景色來(lái)進(jìn)行混合,甚至可以移出頁(yè)面的可見(jiàn)區(qū)域。一旦您的搜尋器訪(fǎng)問(wèn)了這樣的鏈接,您的IP地址就可以被標(biāo)記為進(jìn)一步調(diào)查,甚至被立即阻止。
發(fā)現(xiàn)爬網(wǎng)程序的另一種方法是添加具有無(wú)限深目錄樹(shù)的鏈接。然后,將需要限制檢索頁(yè)面的數(shù)量或限制遍歷深度。
4.做與不做
· 抓取之前,請(qǐng)檢查是否有可用的公共API。與網(wǎng)絡(luò)抓取相比,公共API提供了更輕松,更快(合法)的數(shù)據(jù)檢索。查看提供用于不同目的的API的Twitter API。
· 如果您抓取大量數(shù)據(jù),則可能要考慮使用數(shù)據(jù)庫(kù)來(lái)快速分析或檢索它。遵循本教程,了解如何使用python創(chuàng)建本地?cái)?shù)據(jù)庫(kù)。
· 講禮貌。就像這個(gè)答案所建議的那樣,建議讓人們知道您正在抓捕他們的網(wǎng)站,以便他們可以更好地響應(yīng)您的漫游器可能引起的問(wèn)題。
同樣,不要通過(guò)每秒發(fā)送數(shù)百個(gè)請(qǐng)求來(lái)使網(wǎng)站超載。
5.加速—并行化
如果決定并行化程序,請(qǐng)謹(jǐn)慎執(zhí)行,以免猛烈破壞服務(wù)器。并且確保您閱讀了“注意事項(xiàng)”部分。在此處和此處檢查并行化與并發(fā),處理器和線(xiàn)程的定義。
如果您從頁(yè)面中提取大量信息并在抓取時(shí)對(duì)數(shù)據(jù)進(jìn)行了一些預(yù)處理,則發(fā)送到頁(yè)面的每秒請(qǐng)求數(shù)可能會(huì)相對(duì)較低。
對(duì)于我另一個(gè)刮掉公寓租金價(jià)格的項(xiàng)目,我在刮擦?xí)r對(duì)數(shù)據(jù)進(jìn)行了大量預(yù)處理,結(jié)果是每秒請(qǐng)求1次。為了抓取4K廣告,我的程序?qū)⑦\(yùn)行大約一小時(shí)。
為了并行發(fā)送請(qǐng)求,您可能需要使用多處理程序包。
假設(shè)我們有100個(gè)頁(yè)面,并且我們希望為每個(gè)處理器分配相同數(shù)量的頁(yè)面。如果nCPU的數(shù)量為,則可以將所有頁(yè)面平均分塊到nbin中,然后將每個(gè)bin分配給處理器。每個(gè)進(jìn)程都有其自己的名稱(chēng),目標(biāo)函數(shù)和要使用的參數(shù)。以后可以使用進(jìn)程名稱(chēng)來(lái)將數(shù)據(jù)寫(xiě)入特定文件。
我為4個(gè)CPU分配了1K頁(yè),每秒產(chǎn)生4個(gè)請(qǐng)求,并將抓取時(shí)間減少到大約17分鐘。想了解更多關(guān)于python的信息,請(qǐng)繼續(xù)關(guān)注中培偉業(yè)。