2009-04-17 84 views
7

接下來的一句話引起了我的眼睛在Wget的手冊Web蜘蛛與Wget的蜘蛛有什麼不同?

wget --spider --force-html -i bookmarks.html 

This feature needs much more work for Wget to get close to the functionality of real web spiders. 

我找到相關的代碼在wget的蜘蛛選項以下行。

src/ftp.c 
780:  /* If we're in spider mode, don't really retrieve anything. The 
784:  if (opt.spider) 
889: if (!(cmd & (DO_LIST | DO_RETR)) || (opt.spider && !(cmd & DO_LIST))) 
1227:  if (!opt.spider) 
1239:  if (!opt.spider) 
1268:  else if (!opt.spider) 
1827:   if (opt.htmlify && !opt.spider) 

src/http.c 
64:#include "spider.h" 
2405: /* Skip preliminary HEAD request if we're not in spider mode AND 
2407: if (!opt.spider 
2428:  if (opt.spider && !got_head) 
2456:  /* Default document type is empty. However, if spider mode is 
2570:   * spider mode. */ 
2571:   else if (opt.spider) 
2661:    if (opt.spider) 

src/res.c 
543: int saved_sp_val = opt.spider; 
548: opt.spider  = false; 
551: opt.spider  = saved_sp_val; 

src/spider.c 
1:/* Keep track of visited URLs in spider mode. 
37:#include "spider.h" 
49:spider_cleanup (void) 

src/spider.h 
1:/* Declarations for spider.c 

src/recur.c 
52:#include "spider.h" 
279:  if (opt.spider) 
366:    || opt.spider /* opt.recursive is implicitely true */ 
370:    (otherwise unneeded because of --spider or rejected by -R) 
375:     (opt.spider ? "--spider" : 
378:      (opt.delete_after || opt.spider 
440:  if (opt.spider) 

src/options.h 
62: bool spider;   /* Is Wget in spider mode? */ 

src/init.c 
238: { "spider",   &opt.spider,   cmd_boolean }, 

src/main.c 
56:#include "spider.h" 
238: { "spider", 0, OPT_BOOLEAN, "spider", -1 }, 
435:  --spider     don't download anything.\n"), 
1045: if (opt.recursive && opt.spider) 

我想看看代碼中的差異,而不是抽象的。我喜歡代碼示例。

怎麼辦網絡蜘蛛不同於Wget的在碼蜘蛛

回答

33

一個真正的蜘蛛是很多工作

編寫整個WWW蜘蛛是一項艱鉅的任務---你必須要對多的「小細節」,如護理:

  • 每臺蜘蛛計算機都應該從幾千臺服務器並行接收數據,以便有效利用連接帶寬。 (異步套接字I/O)。
  • 你需要一個並行蜘蛛爲了掩蓋對WWW的大量信息的幾臺電腦;
  • 你需要禮貌的爬行網站(集羣分區的工作):
    • 尊重robots.txt文件。
    • 不要太快地獲取大量信息:這會使服務器負載過重。
    • 不要取,你真的不需要的文件(例如ISO磁盤映像; tgz包軟件下載...)。
  • 您必須處理cookies/session ids:許多站點會將唯一的會話id附加到URL以識別客戶端會話。每次到達該網站時,都會得到一個新的會話ID和一個新的網頁虛擬世界(具有相同的內容)。由於這樣的問題,早期的搜索引擎忽略了動態內容。現代搜索引擎已經知道問題是什麼以及如何處理它們。
  • 你必須檢測和忽略麻煩的數據:即提供對完成太慢數據或連接的無窮盡的連接。
  • 除了以下鏈接,你可能要解析sitemaps得到的網頁的URL。
  • 您可能要評估哪些信息是你和重要的變化比其他網頁更頻繁地頻繁被刷新。注意:整個WWW的蜘蛛會收到大量的數據 - 您需要爲該帶寬付費。您可能想要使用HTTP HEAD請求來猜測頁面是否已更改。
  • 除了接收,你想處理信息並存儲它。 Google會建立索引,爲每個單詞列出包含它的頁面。您可能需要單獨的存儲計算機和基礎設施來連接它們。傳統的關係數據庫不能滿足存儲/索引整個WWW的數據量和性能要求。

這是一個大量的工作。但是如果你的目標比閱讀整個WWW更溫和,你可以跳過一些部分。如果你只是想下載一個wiki的副本等,你可以看看wget的規格。

注意:如果您不相信這麼做太過成功,您可能需要閱讀Google如何重新發明大部分計算機輪子(在基本Linux內核之上)來構建優秀的蜘蛛。即使你削減了很多角落,這也是很多工作。

讓我三點

添加一些新的技術的話

並行連接/異步套接字通信

你可以並行運行的進程或線程數蜘蛛程序。但是,爲了充分利用您的網絡連接,您需要大約5000-10000個並行連接。並行進程/線程的這種數量會產生太多的開銷。

更好的解決方案是異步輸入/輸出:通過在非阻塞模式下打開的套接字和使用epoll的或選擇以處理只在那些已收到數據連接在一個單一的線程化處理約1000並行連接。自Linux內核2.4以來,Linux對可擴展性(我還建議您研究內存映射文件)的優秀支持在後續版本中不斷得到改進。

注意:使用異步I/O比使用「快速語言」更有幫助:最好爲用Perl編寫的1000個連接編寫一個epoll驅動的進程,而不是運行1000個用C編寫的進程。如果你這樣做對,你可以使用perl編寫的進程飽和一個100Mb的連接。

從原來的答案: 這種方法的缺點是,你必須自己實現異步形式(我不知道,這是否可重新使用的庫)的HTTP規範。使用比現代HTTP/1.1協議簡單的HTTP/1.0協議更容易。無論如何,您可能無法從普通瀏覽器的HTTP/1.1的優點中受益,所以這可能是節省一些開發成本的好地方。

五年後編輯: 今天,有很多免費/開源技術可以幫助您完成這項工作。我個人喜歡node.js的異步http implementation ---它爲您節省了上述原始段落中提到的所有工作。當然,今天也有很多模塊可供其他組件在您的蜘蛛中使用。但請注意,第三方模塊的質量可能差異很大。你必須檢查你使用的任何東西。 [老齡問題:]最近,我寫了一個使用node.js的蜘蛛,我發現npm模塊的可靠性,用於鏈接和數據提取的HTML處理不足。對於這份工作,我將這個處理「外包」到用另一種編程語言編寫的過程。但事情很快發生變化,你的時間閱讀本評論,這個問題可能已經是過去的事了......

分區在數臺服務器的工作

一臺計算機無法跟上蜘蛛整個WWW。您需要將您的工作分配到多個服務器並在它們之間交換信息。我建議爲每個服務器分配一定的「域名範圍」:將域名的中央數據庫與參考蜘蛛計算機保持一致。

從接收到的網頁中批量提取URL:根據其域名進行排序;刪除重複項並將它們發送給負責任的蜘蛛計算機。在該計算機上,保留已獲取的URL索引並獲取剩餘的URL。

如果您在每臺蜘蛛計算機上等待提取URL的隊列,則不會有性能瓶頸。但是實現這一點需要很多編程。

閱讀標準

我提到的幾個標準(HTTP/1.x中,robots.txt的,餅乾)。花點時間閱讀並實施它們。如果您只是遵循您知道的網站示例,則會犯錯誤(忘記標準中與您的示例無關的部分內容),併爲使用這些附加功能的網站帶來麻煩。

閱讀HTTP/1.1標準文檔是一件痛苦的事情。但是所有的細節都被添加到了它中,因爲有人真的需要那些細節並且現在使用它。

+0

寫得很好,並說明是一個真正的網絡蜘蛛的挑戰,但我認爲這個問題是指爬行「一個」網站,而不是整個互聯網,可以做得比網絡蜘蛛更好,沒有太多的努力。 – 2009-05-13 19:59:29

4

我不確定這個評論的原始作者究竟是指什麼,但我可以猜測wget作爲一個蜘蛛很慢,因爲它似乎只使用一個單一的執行線程(至少通過你所擁有的示出)。

諸如heritrix之類的「真實」蜘蛛使用大量的並行性和技巧來優化爬行速度,同時對他們爬行的網站很好。這通常意味着以每秒1次的速度限制訪問一個站點,同時抓取多個網站。

再次,這只是一個猜測,根據我所瞭解的蜘蛛的一般情況以及您在此發佈的內容。

2

不幸的是,許多比較知名的'真實'網絡蜘蛛是封閉的,實際上是封閉的二進制。但是有一些基本技巧wget缺失:

  • 並行性;你將永遠無法跟上整個網絡而無需一次檢索多個頁面
  • 優先化;有些頁面比其他頁面更重要蜘蛛
  • 限速;如果您儘可能快地拉下頁面,您將很快被禁止
  • 保存到本地文件系統以外的其他位置; Web足夠大,不適合單個目錄樹
  • 定期重新檢查頁面而不重新啓動整個過程;在實踐中,你需要一個真正的蜘蛛來重新檢查經常更新的「重要」頁面,而不那麼有趣的頁面可能會持續數月。

也有各種其他輸入可以使用,如站點地圖等。需要指出的是,wget並不是爲了捕捉整個網絡而設計的,它不是一個可以在小代碼示例中捕獲的東西,因爲這是整個技術被使用的問題,而不是任何一個小子程序都是錯誤的爲任務。

1

我不打算詳細介紹如何蜘蛛互聯網,我認爲wget評論是關於蜘蛛網站,這仍然是一個嚴峻的挑戰。

  • 當你需要弄清楚什麼時候停止,不進入遞歸蜘蛛抓取,只是因爲URL變了樣日期= 1/1/1900年到1900年1月2日等
  • 更大的挑戰整理URL重寫(我不知道谷歌或任何其他人如何處理這個)。抓取足夠但不太多的挑戰是非常大的挑戰。以及如何使用一些隨機參數和內容中的隨機更改自動識別URL重寫?
  • 您需要解析的Flash/JavaScript的至少到一定程度
  • 你需要考慮像基地標籤一些瘋狂的HTTP問題。即使解析HTML也不容易,因爲大多數網站不是XHTML,瀏覽器在語法上非常靈活。

我不知道在wget中實現或考慮了多少這些,但您可能想看看httrack以瞭解此任務的挑戰。

我很想給你一些代碼示例,但這是大任務和一個體面的蜘蛛將約爲5000位本地沒有第三方庫

+他們中的一些已經被@亞科夫 - 嗝解釋,所以我不打算再鍵入它們