2011-12-17 40 views
3

應該有一個邊界對象 - 保存一組訪問並等待抓取URL。 應該有一些線程負責抓取網頁。 也會有某種控制器對象來創建爬行線程。最快的多線程網絡爬蟲體系結構

我不知道什麼架構會更快,更容易擴展。如何儘可能少的同步來分配責任,並且最小化檢查當前URL是否已經被訪問的次數。

控制器對象是否應該負責爲工作線程提供新的URL - 這意味着工作線程需要抓取所有給定的URL,然後睡眠時間不確定。控制器將解釋這個線程,所以爬行線程應該處理InterruptedException(它在Java中的代價是多少 - 似乎異常處理不是很快)。 或者,也許控制器應該只啓動線程並讓線程自行抓取邊界?

回答

3

創建一個共享的線程安全列表,其中包含要被抓取的URL。創建一個Executor,其線程數與您希望併發運行的抓取工具數量相對應。通過引用共享列表將您的搜尋器作爲Runnables啓動,並將它們分別提交給Executor。每個爬蟲從列表中移除下一個URL並執行您需要的任何操作,循環直到列表爲空。

1

使用哈希映射創建中央資源,該哈希映射可以將URL存儲爲上次掃描時的密鑰。使這個線程安全。然後,只需使用隊列中的鏈接生成線索,這些鏈接可以由抓取工具拾取,作爲起點。然後每個線程將繼續爬行並更新資源。資源中的線程清除過期的爬網。內存資源可以在開始時序列化,也可以在數據庫中根據您的應用需求進行分配。

您可以通過遠程服務訪問此資源以允許多臺計算機。您可以通過隔離網址將資源分散到多臺機器上。等...

1

你應該使用一個阻塞隊列,其中包含需要獲取的URL。在這種情況下,您可以創建多個使用者,以便在多個線程中獲取URL。如果隊列爲空,則所有收件人都將被鎖定。在這種情況下,您應該在開始時運行所有線程,並且不應在稍後控制它們。 此外,您還需要在某些持久性存儲中維護已下載頁面的列表,並在添加到隊列之前進行檢查。

2

它已經幾年,因爲這個問題被問過,但在2015年11月,我們目前正在使用fronterascrapyd

Scrapy使用雙絞線這使它成爲一個很好的多線程爬蟲,並在多核機器,這意味着我們僅受入站帶寬的限制。 Frontera分佈式使用hbase和kafka來對鏈接進行評分,並將所有數據保存到客戶端。