幻影刮伤,休息不起作用

时间:2014-04-22 14:59:12

标签: node.js web-scraping phantomjs sleep

我试图从网络服务中抓取一些URL,它的工作完美,但我需要从同一个网络服务中抓取10,000个页面。

我是通过创建多个phantomJS进程来实现的,它们每个都打开并评估不同的URL(它是相同的服务,我所做的只是网站URL中的一个参数)。

问题是我不想一次打开10,000个页面,因为我不希望他们的服务崩溃,我也不希望我的服务器崩溃。

我试图制作一些打开/评估/插入ToDB~10页的逻辑,然后睡1分钟左右。

让我们说这就是我现在所拥有的:

var numOfRequests = 10,000; //Total requests
    for (var dataIndex = 0; dataIndex < numOfRequests; dataIndex++) {
         phantom.create({'port' : freeport}, function(ph) { 
           ph.createPage(function(page) {
             page.open("http://..." + data[dataIncFirstPage], function(status) {

我想在中间插入一些像:

if(dataIndex % 10 == 0){
   sleep(60); //I can use the sleep module
}

我尝试放置sleepJS的每个地方程序都会永远崩溃/冻结/循环......

知道我应该尝试什么吗?

我尝试将上面的代码放在for循环之后的第一行,但这不起作用(可能是因为等待触发的回调函数..) 如果我把它放在phantom.create()回调中也不起作用..

1 个答案:

答案 0 :(得分:1)

意识到NodeJS是异步运行的,并且在for循环中,每个方法调用都是一个接一个地执行。 phantom.create调用立即接近,然后for循环的下一个循环开始。

要回答你的问题,你需要在phantom.create块末尾的sleep命令,仍然在for循环中。像这样:

var numOfRequests = 10000; // Total requests
for( var dataIndex = 0; dataIndex < numOfRequests; dataIndex++ ) {
  phantom.create( { 'port' : freeport }, function( ph ) {
    // ..whatever in here
  } );
  if(dataIndex % 10 == 0){
    sleep(60); //I can use the sleep module
  }
}

另外,请考虑使用包来帮助解决这些控制流问题。异步是一个很好的,has a method, eachLimit将同时运行多个进程,达到极限。便利!您需要为要运行的每个迭代创建一个输入对象数组,如下所示:

var dataInputs = [ { id: 0, data: "/abc"}, { id : 1, data : "/def"} ];
function processPhantom( dataItem, callback ){
  console.log("Starting processing for " + JSON.stringify( dataItem ) );
  phantom.create( { 'port' : freeport }, function( ph ) {
    // ..whatever in here. 
    //When done, in inner-most callback, call:
    //callback(null); //let the next parallel items into the queue
    //or 
    //callback( new Error("Something went wrong") ); //break the processing
  } );
}
async.eachLimit( dataInputs, 10, processPhantom, function( err ){
  //Can check for err.
  //It is here that everything is finished.
  console.log("Finished with async.eachLimit");
});

睡一分钟并不是一个坏主意,但是以10人为一组,这需要1000分钟,超过16小时!只有在队列中有空间时才能更方便地调用 - 并确保记录正在处理的请求并完成。