如何使用 socket.io 从远程 jquery 客户端控制 CasperJS 自动化脚本
How to control a CasperJS automation script from a remote jquery client using socket.io
我在 CasperJS 中有一个自动化脚本,用于控制登录站点的 PhantomJS 无头浏览器,在多个页面/表单上输入数据。
从同一台物理服务器,我 PHP/MySQL 为 CRM 客户端网站提供服务。在 CRM 网站上,我希望能够:
- 触发远程 CasperJS 脚本去浏览远程站点并登录并填写表单
- 读取输出流(即 "Page 1 complete, page 2 complete" 等)
- 在 CasperJS 脚本执行时向客户端用户显示状态更新
我在想 socket.io 是这里的门票。但是,我这样做是不是错了?我试图避免使用 selenium 服务器 运行。我检查了 this answer on SO 但我不是在寻找屏幕截图,我在寻找要在客户端网站中显示的 CasperJS 的控制台输出。
我曾经有过类似的任务,并使用本地 Express.js 服务器和 Socket.io 制定了一个解决方案。
您将使用 node.js 启动此服务器,然后通过向 http://127.0.0.1:9000
发出 POST 请求将任务从 PHP 传递给它(我使用了出色的 Requests图书馆)。
这是我的脚本的简化版本:
var fs = require("fs");
var express = require("express");
var app = express();
var server = require("http").Server(app);
var io = require("socket.io")(server);
var iosocket;
// Express middleware to get variables from POST request
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
// Create websocket connection
io.on("connection", function(socket){
console.log('io.js connection');
iosocket = socket;
});
// Receieve task from external POST request
app.post("/scrape", function(req, res){
res.send("Request accepted");
// Url to parse
var url = req.body.url;
// Variable to collect data from scraper
var data = [];
// Launch scraping script
var spawn = require('child_process').spawn,
child = spawn('/path/to/casperjs', ['/path/to/scrape/script.js', url]);
console.log("Spawned parser");
// Receieve data from script
child.stdout.on('data', function (data) {
var message = data.toString();
data.push(message);
// Send data to the web client
iosocket.emit("message", message);
});
// On error
child.stderr.on('data', function (data) {
console.log('stderr: ' + data.toString());
});
// On scraper exit
child.on('close', function (code) {
console.log("Scraper exited with code: " + code);
//
// Put data into a file or a database, for example
//
fs.writeFileSync("path/to/file/results_" + (new Date()).getTime() + ".json", JSON.stringify(data));
});
});
// Bind app to port @ localhost
server.listen(9000, "127.0.0.1");
Solution with CasperJS/Phantomjs server 很有趣,但是人们指出它会泄漏内存,如果您 运行 短暂的 CasperJS 脚本,这可能不会发生。
我在 CasperJS 中有一个自动化脚本,用于控制登录站点的 PhantomJS 无头浏览器,在多个页面/表单上输入数据。
从同一台物理服务器,我 PHP/MySQL 为 CRM 客户端网站提供服务。在 CRM 网站上,我希望能够:
- 触发远程 CasperJS 脚本去浏览远程站点并登录并填写表单
- 读取输出流(即 "Page 1 complete, page 2 complete" 等)
- 在 CasperJS 脚本执行时向客户端用户显示状态更新
我在想 socket.io 是这里的门票。但是,我这样做是不是错了?我试图避免使用 selenium 服务器 运行。我检查了 this answer on SO 但我不是在寻找屏幕截图,我在寻找要在客户端网站中显示的 CasperJS 的控制台输出。
我曾经有过类似的任务,并使用本地 Express.js 服务器和 Socket.io 制定了一个解决方案。
您将使用 node.js 启动此服务器,然后通过向 http://127.0.0.1:9000
发出 POST 请求将任务从 PHP 传递给它(我使用了出色的 Requests图书馆)。
这是我的脚本的简化版本:
var fs = require("fs");
var express = require("express");
var app = express();
var server = require("http").Server(app);
var io = require("socket.io")(server);
var iosocket;
// Express middleware to get variables from POST request
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
// Create websocket connection
io.on("connection", function(socket){
console.log('io.js connection');
iosocket = socket;
});
// Receieve task from external POST request
app.post("/scrape", function(req, res){
res.send("Request accepted");
// Url to parse
var url = req.body.url;
// Variable to collect data from scraper
var data = [];
// Launch scraping script
var spawn = require('child_process').spawn,
child = spawn('/path/to/casperjs', ['/path/to/scrape/script.js', url]);
console.log("Spawned parser");
// Receieve data from script
child.stdout.on('data', function (data) {
var message = data.toString();
data.push(message);
// Send data to the web client
iosocket.emit("message", message);
});
// On error
child.stderr.on('data', function (data) {
console.log('stderr: ' + data.toString());
});
// On scraper exit
child.on('close', function (code) {
console.log("Scraper exited with code: " + code);
//
// Put data into a file or a database, for example
//
fs.writeFileSync("path/to/file/results_" + (new Date()).getTime() + ".json", JSON.stringify(data));
});
});
// Bind app to port @ localhost
server.listen(9000, "127.0.0.1");
Solution with CasperJS/Phantomjs server 很有趣,但是人们指出它会泄漏内存,如果您 运行 短暂的 CasperJS 脚本,这可能不会发生。