2015-09-07 85 views
1

下面的腳本包含「links」數組中的一些URL。函數gatherLinks()用於從「鏈接」數組中的URL的sitemap.xml中收集更多URL。一旦「鏈接」數組有足夠的URL(由變量「limit」決定),函數request()被稱爲「links」數組中的每個URL,以向服務器發送請求並獲取響應。報告每個響應所需的時間。程序結束時會報告該程序佔用的總時間。PhantomJS 2.0.0 - 選擇:無效參數錯誤

我寫了一個PhantomJS程序(源代碼如下)發送一些請求並計算所花費的時間(以便比較2.0.0和1.9.8的性能)。我使用「links」數組硬編碼的網站的sitemap.xml文件獲取鏈接。

當使用PhantomJS 2.0.0,一些請求65後的程序(請求功能的方法page.open())開始輸出運行以下:

 
select: Invalid argument 
select: Invalid argument 
select: Invalid argument 
select: Invalid argument 
select: Invalid argument 
. 
. 
. 
. 

當使用PhantomJS 1.9.8運行時,它在大約200崩潰請求出現以下錯誤。

「PhantomJS已經崩潰請務必閱讀正文https://github.com/ariya/phantomjs/wiki/Crash-Reporting崩潰報告指南,並在https://github.com/ariya/phantomjs/issues/new附有崩潰轉儲文件發送錯誤報告:/tmp/2A011800-3367-4B4A-A945-3B532B4D9B0F.dmp」

我試着發送崩潰報告,但他們的指南對我來說並不是很有用。

這不是我使用的網址,我嘗試過使用其他網址,但結果相同。

我的程序有問題嗎?我正在使用OSX。

var system = require('system'); 
var fs = require('fs'); 
var links = []; 

links = [ 
    "http://somesite.com", 
    "http://someothersite.com", 
     . 
     . 
     . 
]; 

var index = 0, fail = 0, limit = 300; 
finalTime = Date.now(); 

var gatherLinks = function(link){ 
    var page = require('webpage').create(); 
    link = link + "/sitemap.xml"; 
    console.log("Fetching links from " + link); 

    page.open(link, function(status){ 
    if(status != "success"){ 
     console.log("Sitemap Request FAILED, status: " + status); 
     fail++; 
     return; 
    } 

    var content = page.content; 
    parser = new DOMParser(); 
    xmlDoc = parser.parseFromString(content, 'text/xml'); 
    var loc = xmlDoc.getElementsByTagName('loc'); 

    for(var i = 0; i < loc.length; i++){ 
     if(links.length < limit){ 
     links[links.length] = loc[i].textContent; 
     } else{ 
     console.log(links.length + " Links prepared. Starting requests.\n"); 
     index = 0; 
     request(); 
     return; 
     } 
    } 

    if(index >= links.length){ 
     index = 0; 
     console.log(links.length + " Links prepared\n\n"); 
     request(); 
    } 

    gatherLinks(links[index++]); 
    }); 
}; 

var request = function(){ 
    t = Date.now(); 
    var page = require('webpage').create(); 
    page.open(links[index], function(status) { 
    console.log('Loading link #' + (index + 1) + ': ' + links[index]); 
    console.log("Time taken: " + (Date.now() - t) + " msecs"); 

    if(status != "success"){ 
     console.log("Request FAILED, status: " + status); 
     fail++; 
    } 
    if(index >= links.length-1){ 
     console.log("\n\nAll links done, final time taken: " + (Date.now() - finalTime) + " msecs"); 
     console.log("Requests sent: " + links.length + ", Failures: " + fail); 
     console.log("Success ratio: " + ((links.length - fail)/links.length)*100 + "%"); 
     phantom.exit(); 
    } 

    index++; 
    request(); 
    }); 
} 

gatherLinks(links[0]); 

在玩完程序之後,我找不到任何特定的模式來解決我在下面提到的問題。對於2.0.0,我只能成功發送300個請求而沒有錯誤。我嘗試了所有不同的URL組合,程序通常在請求50-80之間失敗。我維護一個失敗的URL日誌,當我使用另一個PhantomJS程序發送單個請求時,它們都運行良好。對於1.9.8,它更加穩定,下面我提到的崩潰不是很頻繁。但再一次,我找不到任何崩潰的模式,它偶爾還會崩潰。

+0

我現在已經添加了腳本的說明。請看編輯2 :) @ArtjomB。 – Kakaji

回答

0

你的代碼有很多問題。主要的可能是你爲創建了一個新的頁面,每個請求之後都不會關閉它。我認爲你的內存不足。

我沒有看到爲每個請求創建新頁面的原因,因此您可以輕鬆地爲所有請求重複使用單個頁面。只需將行var page = require('webpage').create();移至gatherLinks()request()以外的全局範圍。如果你不想這樣做,那麼你可以在完成之後調用page.close(),但記住PhantomJS的異步特性。

如果使用多個頁面對象的原因是爲了防止緩存重新用於以後的請求,那麼我不得不告訴你,這並不能解決這個問題。在單個PhantomJS流程中的對象可以被視爲製表符或窗口,並且它們共享cookie和緩存。如果您想隔離每個請求,那麼您需要在自己的進程中運行每個請求,例如通過使用Child Process Module


你的代碼還有另一個問題。您可能需要在gatherLinks()中編寫以下代碼:

if(index >= links.length){ 
    index = 0; 
    console.log(links.length + " Links prepared\n\n"); 
    request(); 
    return; // ##### THIS ##### 
} 

gatherLinks(links[index++]); 
+0

非常感謝。這是我第一次使用JS,所以我認爲這些實例將被垃圾收集。爲每個請求顯式關閉頁面實例並不難,但使用一個全局頁面實例仍然因爲某種原因失敗。也許我錯過了一些東西。但無論如何感謝:) – Kakaji