首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何管理PhantomJS实例的“池”

如何管理PhantomJS实例的“池”
EN

Stack Overflow用户
提问于 2012-04-01 01:41:10
回答 6查看 23.8K关注 0票数 66

我计划在内部使用一个webservice,该服务使用一个参数,即URL,并返回表示该URL中解析的DOM的html。通过解析,我的意思是webservice将首先在该URL上获取页面,然后使用PhantomJS‘呈现’页面,然后在执行所有DHTML、AJAX调用等之后返回结果源。然而,在每次请求的基础上启动幻影(我现在正在做的)太慢了。我希望有一个PhantomJS实例池,其中一个实例总是可用的,以满足对我的webservice的最新调用。

以前做过这种事吗?我宁愿将这个work服务建立在他人的工作上,也不愿从头开始为自己编写一个池管理器/ http代理服务器。

More Context:我列出了下面已经看到的两个类似的项目,以及为什么我避免了每个项目,从而产生了一个关于管理一个PhantomJS实例池的问题。

jsdom --据我所见,它具有在页面上执行脚本的强大功能,但它并不试图复制浏览器行为,所以如果我使用它作为一个通用的"DOM解析器“,最终会有大量额外的编码来处理各种边缘情况、事件调用等。我看到的第一个例子是必须手动调用body标记的onload()函数,以便我使用节点来设置测试应用程序。这似乎是一个深兔子洞的开始。

Selenium -它只是有更多的移动部件,所以设置一个池来管理长期存在的浏览器实例比使用PhantomJS要复杂得多。我不需要任何它的宏记录/脚本的好处。我只想要一个were服务,它在获取网页和解析DOM方面具有同样的性能,就像我用浏览器浏览到那个URL一样(或者如果我可以让它忽略图像等等)。

EN

回答 6

Stack Overflow用户

发布于 2013-10-28 04:30:11

我设置了一个PhantomJs云服务,它可以很好地满足您的要求。我花了大约5个星期的工作工具。

您将遇到的最大问题是已知的幻影in中的内存泄漏问题。我的工作方式是每50个调用循环一次我的实例。

您将遇到的第二个最大问题是每页处理非常占用CPU和内存,因此每个cpu只能运行大约4个实例。

您将遇到的第三个最大问题是,PhantomJ在页面完成事件和重定向方面非常古怪。您将被告知,您的页面在实际呈现之前已经完成呈现。有很多方法可以解决这个问题。,但不幸的是没有什么“标准”。

您必须处理的第四个最大问题是nodejs和幻影is之间的互操作,谢天谢地,还有许多处理这个问题的国家预防机制一揽子计划可供选择。

因此,我知道我有偏见(正如我编写的解决方案,我将建议),但我建议您查看PhantomJsCloud.com,这是免费的轻使用。

2015年1月更新:另一个(5?)我遇到的大问题是如何从管理器/负载均衡器发送请求/响应。最初,我使用的是PhantomJS内置的HTTP服务器,但一直遇到它的限制,特别是在最大响应大小方面。最后,我把对本地文件系统的请求/响应写成了通信线路。*用于实现服务的总时间可能代表20个人工周问题,可能是1000个小时的工作时间。*和FYI我正在为下一个版本做一个完整的重写.(正在进行中)

票数 62
EN

Stack Overflow用户

发布于 2012-04-18 05:21:39

异步JavaScript库在Node中工作,并且有一个非常方便的queue函数来处理这类事情:

queue(worker, concurrency) 创建具有指定并发性的队列对象。添加到队列中的任务将并行处理(直到并发限制)。如果所有工作人员都在进行中,则任务将排队等待,直到可用为止。工作人员完成任务后,任务的回调将被调用。

一些伪码:

代码语言:javascript
运行
复制
function getSourceViaPhantomJs(url, callback) {
  var resultingHtml = someMagicPhantomJsStuff(url);
  callback(null, resultingHtml);
}

var q = async.queue(function (task, callback) {
  // delegate to a function that should call callback when it's done
  // with (err, resultingHtml) as parameters
  getSourceViaPhantomJs(task.url, callback);
}, 5); // up to 5 PhantomJS calls at a time

app.get('/some/url', function(req, res) {
  q.push({url: params['url_to_scrape']}, function (err, results) {
    res.end(results);
  });
});

看看在这个项目的自述中

票数 17
EN

Stack Overflow用户

发布于 2015-12-02 19:07:51

在我的硕士论文中,我开发了一个库幻影池,它就是这样做的。它允许提供作业,然后映射到PhantomJS工作人员。该库处理作业分配、通信、错误处理、日志记录、重新启动等。这个图书馆被成功地用来爬行100多万页。

示例:

下面的代码执行Google搜索0到9的数字,并将页面的截图保存为googleX.png。四个网站被并行爬行(由于创建了四个工人)。脚本是通过node master.js启动的。

master.js (在Node.js环境中运行)

代码语言:javascript
运行
复制
var Pool = require('phantomjs-pool').Pool;

var pool = new Pool({ // create a pool
    numWorkers : 4,   // with 4 workers
    jobCallback : jobCallback,
    workerFile : __dirname + '/worker.js', // location of the worker file
    phantomjsBinary : __dirname + '/path/to/phantomjs_binary' // either provide the location of the binary or install phantomjs or phantomjs2 (via npm)
});
pool.start();

function jobCallback(job, worker, index) { // called to create a single job
    if (index < 10) { // index is count up for each job automatically
        job(index, function(err) { // create the job with index as data
            console.log('DONE: ' + index); // log that the job was done
        });
    } else {
        job(null); // no more jobs
    }
}

worker.js (在PhantomJS环境中运行)

代码语言:javascript
运行
复制
var webpage = require('webpage');

module.exports = function(data, done, worker) { // data provided by the master
    var page = webpage.create();

    // search for the given data (which contains the index number) and save a screenshot
    page.open('https://www.google.com/search?q=' + data, function() {
        page.render('google' + data + '.png');
        done(); // signal that the job was executed
    });

};
票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9961254

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档