我們從爬取1000億個網頁中學到了什麼?

AI前線發表於2019-03-03
策劃編輯 | Natalie
編譯 | 無明
編輯 | Vincent
AI 前線導讀:現如今,爬取網頁看起來似乎是一件很簡單的事。有很多開源框架或庫、視覺化爬取工具和資料提取工具,利用這些工具可以很容易地從網站上爬取資料。但是,當你想大規模爬取網站時,事情就變得棘手起來。其中包括應對不斷變化的網站格式、構建可伸縮的爬蟲基礎框架並保持吞吐量,與此同時還要挫敗網站反機器人的手段以及維護資料質量。在這篇文章中,流行 Python 爬蟲框架 Scrapy 開發者 Scrapinghub 分享了大規模爬取產品資料時將面臨的主要挑戰,以及他們爬取 1000 億個網頁後的經驗之談。

更多幹貨內容請關注微信公眾號“AI 前線”,(ID:ai-front)

Scrapinghub 成立於 2010 年,是一家領先的資料公司,當今最強大、最受歡迎的網路爬取框架 Scrapy 就是由它開發的。目前,Scrapinghub 每個月為全球很多大型的電子商務公司爬取 80 億個網頁(其中有 30 億個是產品頁面)。

在進行大規模爬取時哪些東西是最重要的?

與標準的爬蟲應用程式不同,大規模爬取電子商務產品資料需要面臨一系列獨特的挑戰,這些挑戰讓爬取網頁變得更加困難。

這些挑戰可以被歸結為兩類:速度和資料質量。

因為時間通常是一個限制性的約束條件,所以在進行大規模爬取時要求爬蟲以非常快的速度進行爬取,同時又不影響資料質量。這種對速度的極限要求使得爬取大量產品資料變得極具挑戰性。

挑戰之一:凌亂的程式碼和不斷變化的網頁格式

很顯然,凌亂的程式碼和不斷變化的網頁格式是在大規模爬取資料時將面臨的最大挑戰。不一定是因為任務的複雜性,而是你要在這上面所花費的時間和資源。

如果你做過網店的爬蟲,就會知道,在網店的網頁中,凌亂的程式碼氾濫成災。除了 HTML 格式問題或偶爾出現的字元編碼問題之外,還有其他很多問題。多年來,我們遇到了各種各樣的問題——濫用 HTTP 響應碼、糟糕的 JavaScripts 或濫用 Ajax:

  • 網店在停止銷售某些產品時會刪除相應的產品頁面,但在網站升級後,404 錯誤處理程式卻返回了 200 響應碼。

  • 錯誤地轉義了 JSON 資料,導致某些頁面上的 JavaScript 程式碼無法正常執行(例如’b0rk`d`),你不得不使用正規表示式來爬取資料。

  • 濫用 Ajax,以至於你只能在渲染頁面(導致爬取變慢)或模擬 API 呼叫(導致更多的開發工作量)後才能抓取到你想要的資訊。

這些凌亂的程式碼不僅是你開發爬蟲時的痛點,也會影響到那些視覺化爬蟲工具或自動爬取工具。

在進行大規模爬取時,除了要應對這些凌亂的程式碼,還要面臨網站不斷髮生變化所帶來的挑戰。根據常規經驗,目標網站一般每過 2-3 個月就會修改一次,你的爬蟲就會出問題(導致爬取覆蓋率或質量下降)。

這聽起來可能沒什麼大不了的,但在進行大規模爬取時,這些問題積少成多,就會帶來大麻煩。Scrapinghub 的一個大型電子商務專案使用約 4,000 個爬蟲爬取約 1,000 個電子商務網站,這意味著他們每天會遇到 20-30 個爬蟲失敗。

不同區域和多語言網站的網頁佈局的變化、A/B 測試、產品套件和定價的變化也給爬蟲帶來了更多難題。

沒有簡單的解決方案

對於這些問題,並沒有什麼萬能的靈丹妙藥。很多時候,在擴大規模時往專案中增加更多的資源。以上一個專案為例,該專案的團隊由 18 名全職爬蟲工程師和 3 名專職 QA 工程師組成,以確保能夠源源不斷地向客戶始提供資料。

但是,從經驗來看,你的團隊仍然要學會如何開發更強大的爬蟲,用它們來檢測和處理各種詭異的網頁格式。

最好是隻開發一個可以處理不同頁面佈局的爬蟲,而不是為不同的頁面佈局開發多個爬蟲,爬蟲的可配置下越高越好。

雖然這樣會讓你的爬蟲變複雜(我們的一些爬蟲程式碼長達數千行),但也更容易維護。

大多數公司每天都需要爬取產品資料,因為工程團隊要修復爬蟲問題而不得不等上幾天,這可不是個好主意。在出現這種情況時,Scrapinghub 使用基於機器學習的資料提取工具。這種基於 ML 的提取工具可自動識別目標網站上的目標欄位(產品名稱、價格、貨幣型別、影像、SKU 等)並返回所需的結果。

挑戰之二:可伸縮架構

第二個挑戰是構建一個可伸縮的爬蟲基礎架構,可以隨著請求數量的增加而伸縮,而不會影響到效能。

在大規模爬取產品資料時,一個只能序列化爬取資料的簡單網路爬蟲是不夠的。通常,序列化的爬蟲在一個迴圈中一個接一個地發出請求,每個請求需要 2-3 秒才能完成。

如果你的爬蟲每天發出的請求少於 40,000 個(每 2 秒請求一次相當於每天 43,200 個請求),那麼使用這種方法就足夠了。但是,在此之後,你需要轉換到一種爬蟲架構,這樣才能每天爬取數百萬個網頁,而不會降低效能。

爬取速度是大規模爬取產品資料的關鍵。你要確保能夠在給定的時間內(通常為一天)找到並爬取所有必需的產品頁面。為此,你需要執行以下操作:

實現產品發現和產品抓取的分離

要大規模爬取產品資料,需要將產品發現爬蟲與產品抓取爬蟲分開。

用於產品發現的爬蟲主要負責導航到目標產品類別(或“貨架”),併為產品提取爬蟲儲存該類別下的產品 URL。在產品發現爬蟲將產品 URL 新增到佇列後,產品抓取爬蟲會從該產品頁面爬取目標資料。

Scrapinghub 為此開發了 Frontera(https://github.com/scrapinghub/frontera),並將其開源,雖然 Frontera 最初被設計與 Scrapy 一起使用,但也可以與其他爬蟲框架或獨立專案一起使用。在這篇文章(https://blog.scrapinghub.com/2015/04/22/frontera-the-brain-behind-the-crawls/)中,我們分享瞭如何使用 Frontera 大規模爬取 HackerNews。

為產品爬取分配更多資源

每個產品類別可能包含 10 到 100 個產品,並且爬取產品資料比爬取產品 URL 更耗費資源,因此產品發現爬蟲通常比產品抓取爬蟲執行得更快。所以,你需要為每個發現爬蟲配備多個抓取爬蟲。根據經驗,大約每 100,000 個網頁需要配備一個單獨的抓取爬蟲。

挑戰之三:保持吞吐量

大規模爬取可以比作一級方程式賽車,你的終極目標是從車上卸掉每一克不必要的重量,並以速度的名義榨取發動機最後那一點馬力。大規模網頁爬取也是如此。

在爬取大量資料時,你始終在尋找最小化請求週期時間的方法,並最大限度地提高爬蟲效能,所有這些都是為了能為每個請求減少幾毫秒的時間。

你的團隊需要深入瞭解正在使用的爬蟲框架、代理和硬體,才能調整它們以獲得最佳效能。除此之外,還需要關注:

爬取效率

在進行大規模爬取時,應該儘可能只爬取必要的資料。額外的請求或資料抓取都會降低爬取網站的速度。在設計爬蟲時,請記住以下幾點:

  • 只在逼不得已的情況下才使用 headless 瀏覽器(如 Splash 或 Puppeteer)來解析 JavaScript,因為使用 headless 瀏覽器解析 JavaScript 相當耗費資源,會嚴重影響爬取的速度。

  • 如果可以從產品頁面(如產品名稱、價格、評級等)獲取所需資料而無需請求每個產品頁面,那麼就不要請求產品頁面。

  • 除非真的需要,否則不要請求或抓取影像。

挑戰之四:反機器人措施

如果你正在大規模爬取電子商務網站,肯定會碰到使用反機器人措施的網站。

大多數小型網站使用基本的反機器人措施(比如禁掉頻繁訪問的 IP 地址)。而像亞馬遜這樣大型的電子商務網站會使用像 Distil Networks、Incapsula 或 Akamai 這些複雜的反機器人措施,這讓爬取資料變得更加困難。

代理

因此,在進行大規模產品資料爬取時,首先需要考慮使用代理。你需要大量的代理,並且需要實現 IP 輪換、請求限制、會話管理和黑名單邏輯,防止代理被禁。

除非你已經或者願意養一個龐大的團隊來管理代理,否則應該將這部分爬取過程外包出去。現在有大量的代理服務,他們提供了不同級別的服務。

我們的建議是與代理提供商合作,代理提供商可以為代理配置提供單個端點,並隱藏管理代理的複雜性。大規模爬取非常耗費資源,所以不應該自己重複發明輪子,比如開發和維護自己的內部代理管理基礎設施。

代理之外

不過,僅僅使用代理服務還不足以確保你可以在大型的電子商務網站上規避反機器人措施,越來越多的網站正在使用複雜的反機器人措施來監控你的爬蟲。

這些反機器人措施不僅會讓爬取電子商務網站變得更加困難,如果處理不好,會嚴重影響爬取工具的效能。

在這些反機器人措施中,有很大一部分使用 JavaScript 來判別請求是來自爬蟲還是人類(JavaScript 引擎檢查、字型列舉、WebGL 和 Canvas 等)。

不過之前已經提到,在進行大規模爬取時,要儘量限制使用 headless 瀏覽器(如 Splash 或 Puppeteer)來解析 JavaScript,因為它們非常耗費資源,並且會降低爬取網頁的速度。

因此,為了確保爬蟲的吞吐量,以便每天提供必要的產品資料,你通常需要精心對網站的反機器人措施進行反向工程,在不使用 headless 瀏覽器的情況下讓你的爬蟲搞定一切。

挑戰之五:資料質量

從資料科學家的角度來看,爬蟲專案最重要的考慮因素是所提取資料的質量,而大規模爬取只會讓對資料質量的關注變得更加重要。

每天提取數百萬個資料點,就無法手動驗證所有資料是否乾淨且完好無損。髒資料或不完整的資料很容易進入到你的資料來源並破壞你的資料分析工作。

在爬取同一網站(不同語言,地區等)或不同網站相同產品的多個版本時,尤其需要考慮資料質量問題。

在爬蟲的設計階段,需要進行嚴格的 QA 過程,爬蟲的程式碼需要經過嚴格的評審和測試,確保可以以最可靠的方式提取所需的資料。確保高質量資料的最佳方法是開發自動化 QA 監控系統。

作為資料爬取專案的一部分,需要規劃和開發一個監控系統,在發現資料不一致或發生錯誤時可以發出告警。在 Scrapinghub,我們開發了機器學習演算法,用於檢測:

  • 資料驗證錯誤——每個資料項都有定義好的資料型別,它們的值都遵循一致的模式。我們的資料驗證演算法可以標記出與資料型別的預期不一致的資料項,QA 團隊將手動檢查這些資料,併發出告警或將其標記為錯誤。

  • 產品差異錯誤——從同一網站的多個版本(不同語言、地區等)爬取相同的產品資料時,一些變數(如產品重量或尺寸)可能會有不同的值。這可能是網站的反機器人措施為爬蟲提供的偽造資訊。同樣,你需要有適當的演算法來識別和標記此類資料。

  • 資料量不一致性——另一個關鍵的監控動作是檢測異常的返回資料量。如果出現異常,可能是因為網站已經發生了變更,或者網站向你的爬取工具提供了偽造資訊。

  • 網站變更——目標網站發生的結構性變更是導致爬取工具崩潰的主要原因。我們的專用監控系統對此進行監控,它會頻繁地檢查目標網站,確保自上次爬取以來沒有發生任何變更。如果發生變更,它會傳送通知。

總 結

本文介紹了在進行大規模爬取產品資料時需要面對的一系列獨特的挑戰。對於那些有興趣瞭解大規模網站爬取的人,可以進一步參閱 Enterprise Web Scraping: A Guide to Scraping the Web at Scale(https://info.scrapinghub.com/enterprise-web-scraping-scraping-at-scale)。

英文原文:

https://blog.scrapinghub.com/web-scraping-at-scale-lessons-learned-scraping-100-billion-products-pages

相關文章