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