2012-07-11 60 views
13

我使用的是基於webkit的工具來構建一個用於爬網頁面的無頭瀏覽器(我需要這個是因爲我想評估在頁面上找到的JavaScript並獲取最終呈現的頁面)。但是,迄今爲止我所實施的兩種不同的系統表現出非常差的性能。我已經實現了兩個不同的系統,它們都使用的webkit作爲後端:使用webkit進行無頭瀏覽

  1. 使用谷歌瀏覽器:我將開始谷歌瀏覽器,並使用由Chrome用於遠程調試(debugging over wire)暴露的WebSockets每個標籤通信。這樣我就可以控制每個選項卡,加載一個新頁面,並且一旦加載頁面,我就可以獲取加載的網頁的DOM。
  2. 使用phantomjs:phantomjs使用webkit加載頁面並提供無頭瀏覽選項。正如phantomjs的例子中所解釋的那樣,我使用page.open打開一個新的URL,然後通過在頁面上評估JavaScript來加載頁面後獲取dom。

我的目標是儘可能快地抓取頁面,並且如果頁面在前10秒內不加載,則聲明失敗並繼續前進。我知道每個頁面需要一段時間才能加載,因此爲了增加每秒加載的頁面數量,我在Chrome中打開了許多選項卡,或者使用phantomjs啓動多個並行進程。以下是我觀察到的表現:

  1. 如果我在Chrome/20 phantomjs情況下,CPU使用率高達火箭開20餘個標籤。
  2. 由於CPU使用率高,大量頁面加載時間超過10秒,因此我的故障率更高(約80%的頁面加載請求失敗)
  3. 如果我打算保持失敗超過請求總數的5%,我無法每秒載入超過1個網址。

嘗試了兩種基於WebKit系統後,感覺就像性能瓶頸是WebKit渲染引擎,因此想從其他用戶在此瞭解,我可以期待抓取每秒的URL的數量。我的硬件配置是:

  1. 處理器:英特爾睿™i7-2635QM(1個處理器,4個內核)
  2. 顯卡:AMD的Radeon HD 6490M(256MB)
  3. 內存:4GB
  4. 網絡帶寬是足夠好,能夠加載頁面比我觀察到的性能更多

我想問這個郵件列表的問題是,是否有任何人使用webkit的隨機爬行網頁的經驗一套網址(比如說從twitter流中選擇10k網址),我可以合理預計每秒會抓取多少個網址?

感謝

+1

我會在一個月左右的時間裏知道你的問題的答案:)我正在使用'Node.js'和'PhantomJS'做類似的事情(但我想評估其他的東西)。與此同時,我將從您可能得到的答案中受益! – 2012-07-15 03:33:38

回答

3

這個問題實際上是更加相關的硬件比軟件,但讓我指出你在一些更好的方向呢。

首先,瞭解每個頁面本身產生多個線程。它將下載頁面,然後開始爲頁面上的元素(如javascript文件,css文件和圖像)生成新的下載線程。[Ref:http://blog.marcchung.com/2008/09/05/chromes-process-model-explained.html]

因此,根據頁面的結構,最終可能會有相當數量的線程在同一時間只爲頁面添加,最多添加一次嘗試一次執行太多負載你有問題。

Optimal number of threads per core的堆棧溢出線程提供了有關您遇到的情況的更多信息。你的CPU超載。

您的處理器是4個物理8個邏輯核心。我建議一次產生不超過4個連接,讓次要邏輯核心處理一些線程。你可能會發現你甚至需要減少這個數字,但4是一個很好的起點。通過一次渲染第4頁,而不是重載整個系統試圖渲染20,你實際上會提高你的整體速度,因爲你最終的緩存交換要少得多。從幾個易於定時的地點開始計時。然後嘗試更少和更多。會有一個甜蜜點。請注意,PhantomJS的無頭瀏覽器版本可能會更好,因爲在無頭模式下它可能不會下載圖像(一個加號)。

儘管您最好的總體選擇是通過http://www.webkit.org/自己使用webkit源代碼進行部分頁面渲染。由於看起來你需要渲染的是html和javascript。這可以減少連接數量,並使您可以更高效地控制線程。你可以在這種情況下創建一個事件隊列,將所有的主網址都放到那裏。產生4個工作線程,所有工作線程都工作在工作隊列中,當他們處理一個頁面並需要下載更多的源代碼時,他們可以將這些更多的下載添加到隊列中。一旦一個頁面的所有文件都被下載到內存中(或者如果你擔心ram的話,則是磁盤),然後你可以在事件隊列中添加一個項目來渲染頁面,然後解析它,以滿足你需要的任何內容。