Multithreading for循环中的PhantomJS节点
我正在尝试实现一个screen scrape应用程序,该应用程序打开一个URL,其中一个参数发生更改,这是在for循环中完成的,如下所示:Multithreading for循环中的PhantomJS节点,multithreading,node.js,multiprocessing,screen-scraping,phantomjs,Multithreading,Node.js,Multiprocessing,Screen Scraping,Phantomjs,我正在尝试实现一个screen scrape应用程序,该应用程序打开一个URL,其中一个参数发生更改,这是在for循环中完成的,如下所示: var data=['100','101','102','103','104']; for(var indexA = 0 ; indexA < data.length ; indexA++){ phantom.create({'port' : freeport}, function(ph) { ph.createPa
var data=['100','101','102','103','104'];
for(var indexA = 0 ; indexA < data.length ; indexA++){
phantom.create({'port' : freeport}, function(ph) {
ph.createPage(function(page) {
page.open("http://..."+ data[indexB] + "...", function(status) {
console.log("opened site: " + data[indexB], status);
/*OLD*/ indexB++;
page.evaluate(function() { //Scrape the page and return an object
},function(result){
console.log(result.dataRequest); //Here is the problem
}); /*NEW AND FIXED*/ indexB++
}
这很好
dataRequest位于已删除的HTML中,并与数组中的索引相对应。因此,在第101页中,我刮取并检索“101”并输入结果。
但是,当我控制台记录result.dataRequest时,我得到:
100
101
102
102
102
我的理论是:
与多重处理问题有关。我不知道新的phantomJS子进程是什么时候创建的,什么时候删除的。我是否应该在结果回调周围放置某种互斥体(互斥体的JS版本…)?
这导致了一个问题,因为我想将结果插入到数据库中,当我检查我的数据库时,我会看到相同结果的重复项
谢谢大家! imo,问题是js是异步的。看起来您的循环比phantomjs创建方法处理得更快 您无法确定异步方法将如何运行(关于调用顺序和内容) 我的意思是,在您的示例中,大多数情况下,您无法确定phantom.create订单会在上一个indexB++之后发生 显然,在您的日志中,它适用于100101102,但是在第四个循环中,您创建了幻影实例,然后启动了一个新的循环,但是“indexB++;”步骤还没有发生。因此,您使用相同的indexB再次执行步骤循环 tl,dr: 在您的情况下,会发生以下情况:
create.phantom for 100
100++
create.phantom for 101
101++
create.phantom for 102
create.phantom for 102
create.phantom for 102
102++
103++
104++
您可以使用的是处理异步工作流。在我看来,问题是js是异步的。看起来您的循环比phantomjs创建方法处理得更快 您无法确定异步方法将如何运行(关于调用顺序和内容) 我的意思是,在您的示例中,大多数情况下,您无法确定phantom.create订单会在上一个indexB++之后发生 显然,在您的日志中,它适用于100101102,但是在第四个循环中,您创建了幻影实例,然后启动了一个新的循环,但是“indexB++;”步骤还没有发生。因此,您使用相同的indexB再次执行步骤循环 tl,dr: 在您的情况下,会发生以下情况:
create.phantom for 100
100++
create.phantom for 101
101++
create.phantom for 102
create.phantom for 102
create.phantom for 102
102++
103++
104++
您可以使用的是处理异步工作流。循环中的异步方法总是很棘手的。我为Call写了一个备选方案。它没有将所有函数调用和赋值转换为异步操作,而是在PhantomJS中执行整个函数 而不是
var data = ['100','101','102','103','104'];
for(var indexA = 0; indexA < data.length; indexA++){
phantom.create({'port' : freeport}, function(ph) {
ph.createPage(function(page) {
page.open("http://..."+ data[indexB] + "...", function(status) {
console.log("opened site: " + data[indexB], status);
page.evaluate(function() {
//Scrape the page and return an object
}, function (result) {
console.log(result.dataRequest); //Here is the problem
});
});
});
});
}
循环内部的异步方法总是很棘手的。我为Call写了一个备选方案。它没有将所有函数调用和赋值转换为异步操作,而是在PhantomJS中执行整个函数 而不是
var data = ['100','101','102','103','104'];
for(var indexA = 0; indexA < data.length; indexA++){
phantom.create({'port' : freeport}, function(ph) {
ph.createPage(function(page) {
page.open("http://..."+ data[indexB] + "...", function(status) {
console.log("opened site: " + data[indexB], status);
page.evaluate(function() {
//Scrape the page and return an object
}, function (result) {
console.log(result.dataRequest); //Here is the problem
});
});
});
});
}
我将indexB++的位置更改为pageOpen的末尾,而不是在其回调中。这成功了!我将indexB++的位置更改为pageOpen的末尾,而不是在其回调中。这成功了!