필자는 페이지를 긁는 데 아주 오랜 시간이 걸린다는 점을 제외하면 매우 잘 작동하는 CasperJS 스크립트를 작성했습니다. 간단히 말해서 수천 개의 페이지를 스크랩하는 CasperJS 스크립트를 더 빨리 실행하는 모범 사례
, 여기에 의사 코드입니다 : 요소를casper.start()
탐색을 시작하고 로그인하는casper.then()
에서 나는 루프를 통해 배열을 스크랩 및 저장
- 내 기능 내
casper.thenOpen()
각 링크를 열고 내 기능을 스크랩하도록 호출하십시오.
많은 링크를 폐기하는 데 완벽하게 (그리고 충분히 빠름) 작동합니다. 하지만 수천의 경우 (지금은 100K 링크 어레이로 스크립트를 실행하고 있습니다), 실행 시간은 무한합니다. 첫 번째 10K 링크는 3h54m10s에서, 다음 10K는 2h18m27s에서 스크랩되었습니다.
2 개의 10K 배치의 차이를 약간 설명 할 수 있습니다. 첫 번째는 루프 배열 &의 100K 링크 저장 공간을 포함합니다. 이 시점부터 스크립트는 페이지를 열어 스크랩합니다. 그러나 배열이 대략 30 분 후에 갈 준비가되었음을 알았으므로 정확히 시간 차이를 설명하지 못합니다.
각 루프가 빌드되어 어레이에 저장된 후 스크랩이 발생하기를 바라는 for 루프에 casper.thenOpen()
을 삽입했습니다. 지금, 나는 이것이 실패 했음에도 불구하고 성능 측면에서 어떤 것도 바꿀 것인가?
그 점은 제가 지금 염두에 두어야 할 유일한 단서입니다. 스크립트 실행의 실행 시간을 크게 줄이려면 누구나 기꺼이 최선의 방법을 공유하고 싶다면 매우 감사 할 것입니다. . 아마 답변보다 더 많은 질문을 가지고 있지만의 시도하자이 시점에서
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();
});
답장을 보내 주셔서 감사합니다 @ 익명! PhantomJS, CasperJS 및 SlimmerJS가 웹 스크래핑에 가장 많이 사용되는 언어라는 것을 알고 있었기 때문에 Curl을 고려하지 않았습니다. 당신의 답을 바탕으로, 컬이 트릭을 할 것 같아요. 그래서 나는 확실히 그 장면을 보여줄 것입니다. 내가 import.io를 사용하여 근근이 살아가고 있지만, 나는 자신의 계획을 감당할 수 없어서 CasperJS에 자신을 가르치기로 결심했다. 수십만 개의 웹 페이지를 다 써야 할 필요가 있기 때문에 URL을 저장하기 위해 커다란 배열이 필요합니다. 나는 여기에 다시 메모리를 할당하지 않았고, 이것 역시 시도해보고 결과를 비교할 것입니다. 내 코드를 내 질문으로 업데이트했습니다.) – DFATPUNK