我寫了一個CasperJS腳本,除了需要(非常非常)很長的時間才能清除頁面,其效果非常好。更快地執行廢棄成千上萬頁的CasperJS腳本的最佳實踐
概括地說,這裏的僞代碼:
- 我的功能報廢元素
- 我
casper.start()
啓動導航並登錄 casper.then()
,我遍歷數組和存儲我鏈接casper.thenOpen()
打開每個鏈接並調用我的函數來報廢。
它工作完美(和足夠快)的廢除一堆鏈接。但是當涉及到數千個(現在我正在運行帶有100K鏈接數組的腳本)時,執行時間是無止境的:第一個10K鏈接已經在3小時54分10秒內被報廢,接下來的10K在2小時18分27秒內被報廢。
我可以解釋兩個10K批次之間的差異:第一個包括循環&與100K鏈接數組的存儲。從這一點來看,腳本只會打開頁面來取消它們。不過,我注意到陣列已經準備好了,大概需要30分鐘,所以它不能準確解釋時間間隔。
我已經將我的casper.thenOpen()
放在for循環中,希望在構建並存儲在數組中的每個新鏈接之後都會發生報廢。現在,我確定我已經失敗了,但它會改變性能方面的任何事情嗎?
這是我現在唯一想到的領導,如果有人願意分享他/她的最佳實踐,以顯着減少腳本執行的運行時間(應該不難!)。 。
編輯#1
這裏是我下面的代碼:
var casper = require('casper').create();
var fs = require('fs');
// This array maintains a list of links to each HOL profile
// Example of a valid URL: https://myurl.com/list/74832
var root = 'https://myurl.com/list/';
var end = 0;
var limit = 100000;
var scrapedRows = [];
// Returns the selector element property if the selector exists but otherwise returns defaultValue
function querySelectorGet(selector, property, defaultValue) {
var item = document.querySelector(selector);
item = item ? item[property] : defaultValue;
return item;
}
// Scrapping function
function scrapDetails(querySelectorGet) {
var info1 = querySelectorGet("div.classA h1", 'innerHTML', 'N/A').trim()
var info2 = querySelectorGet("a.classB span", 'innerHTML', 'N/A').trim()
var info3 = querySelectorGet("a.classC span", 'innerHTML', 'N/A').trim()
//For scrapping different texts of the same kind (i.e: comments from users)
var commentsTags = document.querySelectorAll('div.classComments');
var comments = Array.prototype.map.call(commentsTags, function(e) {
return e.innerText;
})
// Return all the rest of the information as a JSON string
return {
info1: info1,
info2: info2,
info3: info3,
// There is no fixed number of comments & answers so we join them with a semicolon
comments : comments.join(' ; ')
};
}
casper.start('http://myurl.com/login', function() {
this.sendKeys('#username', 'username', {keepFocus: true});
this.sendKeys('#password', 'password', {keepFocus: true});
this.sendKeys('#password', casper.page.event.key.Enter, {keepFocus: true});
// Logged In
this.wait(3000,function(){
//Verify connexion by printing welcome page's title
this.echo('Opened main site titled: ' + this.getTitle());
});
});
casper.then(function() {
//Quick summary
this.echo('# of links : ' + limit);
this.echo('scraping links ...')
for (var i = 0; i < limit; i++) {
// Building the urls to visit
var link = root + end;
// Visiting pages...
casper.thenOpen(link).then(function() {
// We pass the querySelectorGet method to use it within the webpage context
var row = this.evaluate(scrapDetails, querySelectorGet);
scrapedRows.push(row);
// Stats display
this.echo('Scraped row ' + scrapedRows.length + ' of ' + limit);
});
end++;
}
});
casper.then(function() {
fs.write('infos.json', JSON.stringify(scrapedRows), 'w')
});
casper.run(function() {
casper.exit();
});
感謝您的回答@匿名!我沒有考慮過Curl,因爲我只知道PhantomJS,CasperJS和SlimmerJS是網絡報廢最流行的語言。基於你的回答,我認爲Curl可能會做到這一點,所以我肯定會給它一個鏡頭。我使用import.io進行刮擦,但是我無法承受他們的計劃,所以我決定自學自己的CasperJS。我需要抓取數十萬個網頁,所以在某些時候,我需要大型數組來存儲URL。我沒有在這裏再分配內存,我也會嘗試這個,並比較結果。我用我的代碼更新了我的問題;) – DFATPUNK