【发布时间】:2016-05-05 04:14:33
【问题描述】:
我的目标是系统地收集有关网页上每个元素的信息。具体来说,我想对每个元素执行el.getBoundingClientRect() 和window.getComputedStyle(el)。
我一直在使用 Selenium WebDriver for NodeJS 来加载页面和管理浏览器交互。为简化起见,我们只关注getComputedStyle:
driver.findElements(By.xpath("//*"))
.then(elements => {
var elementsLeft = elements.length;
console.log('Entering async map');
async.map(elements, el => {
driver.executeScript("return window.getComputedStyle(arguments[0]).cssText",el)
.then((styles: any) => {
//stuff would be done here with the styles
console.log(elements.indexOf(el));
});
});
});
这段代码将遍历所有元素并检索它们的样式,但它非常慢。完成一个页面可能需要几分钟。我希望驱动程序异步执行脚本,但这似乎不可能,因为每个 Selenium 驱动程序都有一个“ControlFlow”,可确保驱动程序的每个命令仅在最后一个完成后启动。我需要为此找到一种解决方法,以便我可以在页面上异步执行 javascript(并使我的数据收集更快)。
注意:我也尝试过 Selenium 的 executeAsyncScript,结果证明它只是 executeScript 的一个包装器,并且在完成之前仍会阻塞。这是我使用 executeAsyncScript 的代码 - 它的性能与之前的代码一样好:
driver.findElements(By.xpath("//*"))
.then(elements => {
var elementsLeft = elements.length;
async.map(elements, el => {
driver.executeAsyncScript(
function(el: any) {
var cb = arguments[arguments.length - 1];
cb(window.getComputedStyle(el).cssText);
}, el)
.then((styles: any) => {
//stuff would be done here with the styles
console.log(elements.indexOf(el));
});
});
});
我正在寻找一种方法来绕过 Selenium 的 ControlFlow 以异步执行我的 javascript,找到一种方法来提取对象并且不受驱动程序的约束,或者找到一种替代工具/解决方案来获取数据我需要。
【问题讨论】:
标签: javascript node.js asynchronous selenium-webdriver webdriver