我使用Selenium的node.js API针对一系列网页运行PhantomJS实例。我用来在页面上执行操作的代码运行正常,但似乎只有一个Selenium / PhantomJS实例可以一次运行。这个函数在同一个模块中被多次调用,并逐步遍历网上商店中的页面,在这里,客户端处理分页(这就是为什么我需要Selenium / PhantomJS环境 - 从每个页面中提取数据)。
再一次,代码本身工作正常,但它无法并行执行。可能导致这种情况的原因是什么?
module.exports = function (crawler, page, parsePage, done) {
"use strict";
var _ = require("lodash"),
format = require("util").format,
path = require("path"),
webdriver = require("selenium-webdriver"),
By = webdriver.By,
until = webdriver.until;
var phantomPath = path.resolve(__dirname, "../node_modules/.bin/phantomjs"),
isWin = process.platform === "win32";
var driver = new webdriver.Builder()
.withCapabilities({
"phantomjs.binary.path": isWin ? phantomPath + ".cmd" : phantomPath
})
.forBrowser("phantomjs")
.build();
var windowHandle = new webdriver.WebDriver.Window(driver);
windowHandle.setSize(1100, 1000);
var getAllPagesContent = function (driver) {
var pagesContent = [],
pageNo = 1;
var getNextPage = function () {
var nextPageLink;
return driver.findElements(By.css(".pagination li")).then(function (elements) {
return elements[elements.length - 1];
}).then(function (element) {
nextPageLink = element;
return element.getAttribute("class");
}).then(function (className) {
return _.includes(className, "active");
}).then(function (isLastPage) {
return (!isLastPage) ? driver.getPageSource() : false;
}).then(function (content) {
if (content)
pagesContent.push(content);
content && console.log("Got page %d", pageNo++);
return nextPageLink.findElement(By.css("a")).then(function (element) {
return element.click();
}).then(function () {
return driver.wait(until.stalenessOf(nextPageLink), 10 * 1000);
}).then(function () {
return content ? getNextPage() : pagesContent;
});
});
};
return getNextPage();
};
var processTimeout = setTimeout(function () {
console.log("PhantomJS for page %s took too long to execute", page.url);
driver.quit().then(done);
}, 60 * 1000);
driver.get(page.url).then(function () {
var pageOverlay = driver.findElement(By.css("#overlay-the-new"));
return pageOverlay.isDisplayed().then(function (visible) {
if (visible) {
pageOverlay.click();
return driver.wait(until.elementIsNotVisible(pageOverlay), 10000);
}
}).then(function () {
return getAllPagesContent(driver);
});
}).then(function (contents) {
clearTimeout(processTimeout);
console.log("Got %d pages for %s", contents.length, page.url);
_.forEach(contents, function (pageContent) {
parsePage(page.url, pageContent);
});
return driver.quit();
}).then(function () {
done();
});
}
答案 0 :(得分:1)
虽然现在不推荐使用PhantomJS,但您仍然可以使用Docker在并行隔离的Selenoid容器中运行它。这里有一个可以使用的最新版本的图像:https://hub.docker.com/r/selenoid/phantomjs/tags/
答案 1 :(得分:0)
使用Remote WebDrivers和Selenium Grid2 Framework进行与Selenium的并行执行。
这个教程WeDoQA似乎是你想要的东西。简单地说,它将每个测试放在一个单独的类中,而中央测试基类指向Grid2的中心,然后(在教程中)使用Firefox驱动程序并行执行测试。您可以轻松地重新调整此项以使用phantomjs,但您可能需要重新设计测试结构。
答案 2 :(得分:0)
看起来你只使用一个驱动程序。我初始化第二个驱动程序,然后使用线程并行运行。我认为这可以完成工作。
答案 3 :(得分:-1)
使用Thread并行运行,或者您可以使用任何可以并行运行测试的测试框架。