如何使用 Phantomjs 设置页面抓取之间的时间间隔
How to set time interval between page scraping with Phantomjs
目前我用 Phantomjs 写了一个脚本,它可以抓取多个页面。我的脚本有效,但我不知道如何在两次擦除之间设置时间间隔。我尝试使用 setInterval
并大约每 5 秒从 arrayList
传递项目,但它似乎不起作用。我的剧本一直在崩溃。这是我的示例 phantomjs 脚本代码:
没有setInterval
var arrayList = ['string1', 'string2', 'string3'....]
arrayList.forEach(function(eachItem) {
var webAddress = "http://www.example.com/eachItem"
phantom.create(function(ph) {
return ph.createPage(function(page) {
return page.open(yelpAddress, function(status) {
console.log("opened site? ", status);
page.injectJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function() {
setTimeout(function() {
return page.evaluate(function() {
//code here for gathering data
}, function(result) {
return result
ph.exit();
});
}, 5000);
});
});
});
});
与setInterval
:
var arrayList = ['string1', 'string2', 'string3'....]
var i = 0
var scrapeInterval = setInterval(function() {
var webAddress = "http://www.example.com/arrayList[i]"
phantom.create(function(ph) {
return ph.createPage(function(page) {
return page.open(yelpAddress, function(status) {
console.log("opened site? ", status);
page.injectJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function() {
setTimeout(function() {
return page.evaluate(function() {
//code here for gathering data
}, function(result) {
return result
ph.exit();
});
}, 5000);
});
});
});
i++
if(i > arrayList.length) {
clearInterval(scrapeInterval);
}, 5000);
基本上,我想在 arrayList
内发送一大块项目(其中 10-20 个)并等待 1 - 2 分钟,然后发送下一批项目,而不会压倒网站。或者,如果有一种方法可以设置一个时间间隔以每 2-3 秒循环一次数组中的每个项目。
您在添加 setInterval
方法的第二个片段中有一些拼写错误:
var arrayList = ['string1', 'string2', 'string3'];
var i = 0;
var scrapeInterval = setInterval(function () {
var webAddress = "http://www.example.com/arrayList[i]"
phantom.create(function (ph) {
return ph.createPage(function (page) {
return page.open(yelpAddress, function (status) {
console.log("opened site? ", status);
page.injectJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function () {
setTimeout(function () {
return page.evaluate(function () {
//code here for gathering data
}, function (result) {
return result
ph.exit();
});
}, 5000);
});
});
});
i++;
if (i > arrayList.length) {
clearInterval(scrapeInterval);
} //This was missing;
}); //This was missing;
}, 5000);
我注意到的是以下超时中的 return
语句:
setTimeout(function () {
return page.evaluate(function () {
//code here for gathering data
}, function (result) {
return result
ph.exit();
});
}, 5000);
ph.exit();
永远无法到达,我不知道这是否会给您带来任何问题,但您可能想看看它。
问题是PhantomJS是异步的,但是循环迭代不是。所有迭代(在第一个代码段中)甚至在加载第一页之前就已执行。您实际上是在同时生成多个这样的进程 运行。
你可以使用类似async的东西让它运行顺序:
phantom.create(function(ph) {
ph.createPage(function(page) {
var arrayList = ['string1', 'string2', 'string3'....];
var tasks = arrayList.map(function(eachItem) {
return function(callback){
var webAddress = "http://www.example.com/" + eachItem;
page.open(webAddress, function(status) {
console.log("opened site? ", status);
page.injectJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function() {
setTimeout(function() {
return page.evaluate(function() {
//code here for gathering data
}, function(result) {
callback(null, result);
});
}, 5000);
});
});
};
});
async.series(tasks, function(err, results){
console.log("Finished");
ph.exit();
});
});
});
当然你也可以将phantom.create()
移动到每个任务中,这将为每个请求创建一个单独的进程,但上面的代码会更快。
目前我用 Phantomjs 写了一个脚本,它可以抓取多个页面。我的脚本有效,但我不知道如何在两次擦除之间设置时间间隔。我尝试使用 setInterval
并大约每 5 秒从 arrayList
传递项目,但它似乎不起作用。我的剧本一直在崩溃。这是我的示例 phantomjs 脚本代码:
没有setInterval
var arrayList = ['string1', 'string2', 'string3'....]
arrayList.forEach(function(eachItem) {
var webAddress = "http://www.example.com/eachItem"
phantom.create(function(ph) {
return ph.createPage(function(page) {
return page.open(yelpAddress, function(status) {
console.log("opened site? ", status);
page.injectJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function() {
setTimeout(function() {
return page.evaluate(function() {
//code here for gathering data
}, function(result) {
return result
ph.exit();
});
}, 5000);
});
});
});
});
与setInterval
:
var arrayList = ['string1', 'string2', 'string3'....]
var i = 0
var scrapeInterval = setInterval(function() {
var webAddress = "http://www.example.com/arrayList[i]"
phantom.create(function(ph) {
return ph.createPage(function(page) {
return page.open(yelpAddress, function(status) {
console.log("opened site? ", status);
page.injectJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function() {
setTimeout(function() {
return page.evaluate(function() {
//code here for gathering data
}, function(result) {
return result
ph.exit();
});
}, 5000);
});
});
});
i++
if(i > arrayList.length) {
clearInterval(scrapeInterval);
}, 5000);
基本上,我想在 arrayList
内发送一大块项目(其中 10-20 个)并等待 1 - 2 分钟,然后发送下一批项目,而不会压倒网站。或者,如果有一种方法可以设置一个时间间隔以每 2-3 秒循环一次数组中的每个项目。
您在添加 setInterval
方法的第二个片段中有一些拼写错误:
var arrayList = ['string1', 'string2', 'string3'];
var i = 0;
var scrapeInterval = setInterval(function () {
var webAddress = "http://www.example.com/arrayList[i]"
phantom.create(function (ph) {
return ph.createPage(function (page) {
return page.open(yelpAddress, function (status) {
console.log("opened site? ", status);
page.injectJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function () {
setTimeout(function () {
return page.evaluate(function () {
//code here for gathering data
}, function (result) {
return result
ph.exit();
});
}, 5000);
});
});
});
i++;
if (i > arrayList.length) {
clearInterval(scrapeInterval);
} //This was missing;
}); //This was missing;
}, 5000);
我注意到的是以下超时中的 return
语句:
setTimeout(function () {
return page.evaluate(function () {
//code here for gathering data
}, function (result) {
return result
ph.exit();
});
}, 5000);
ph.exit();
永远无法到达,我不知道这是否会给您带来任何问题,但您可能想看看它。
问题是PhantomJS是异步的,但是循环迭代不是。所有迭代(在第一个代码段中)甚至在加载第一页之前就已执行。您实际上是在同时生成多个这样的进程 运行。
你可以使用类似async的东西让它运行顺序:
phantom.create(function(ph) {
ph.createPage(function(page) {
var arrayList = ['string1', 'string2', 'string3'....];
var tasks = arrayList.map(function(eachItem) {
return function(callback){
var webAddress = "http://www.example.com/" + eachItem;
page.open(webAddress, function(status) {
console.log("opened site? ", status);
page.injectJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function() {
setTimeout(function() {
return page.evaluate(function() {
//code here for gathering data
}, function(result) {
callback(null, result);
});
}, 5000);
});
});
};
});
async.series(tasks, function(err, results){
console.log("Finished");
ph.exit();
});
});
});
当然你也可以将phantom.create()
移动到每个任务中,这将为每个请求创建一个单独的进程,但上面的代码会更快。