通过web驱动程序异步执行Javascript
Asynchronously execute Javascript through a web driver
我的目标是系统地收集网页上每个元素的相关信息。具体来说,我想对每个元素执行el.getBoundingClientRect()
和window.getComputedStyle(el)
。
我一直在使用SeleniumWebDriverforNodeJS来加载页面和管理浏览器交互。为了简化,我们只关注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的executeSyncScript,它只是executeScript的一个包装器,在完成之前仍然会阻塞。这是我使用executeSyncScript的代码,它的性能与前一个代码一样好:
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,找到一种提取对象而不受驱动程序绑定的方法,或者找到一种替代工具/解决方案来获取我需要的数据。
由于executeScript
可以占用WebElement
s,您看到在一个调用中完成所有工作是否比重复调用executeScript
更快吗?
driver.findElements(By.xpath("//*"))
.then(elements => {
driver.executeScript("return arguments[0].map(function(el) {return [el, window.getComputedStyle(el).cssText];})", elements)
.then((styles: any) => {
//stuff would be done here with the styles
console.log(styles);
});
});
});
如果速度太慢,您是否考虑过定位脚本中的所有元素,而不是将它们传入?
driver.findElements(By.xpath("//*"))
.then(elements => {
driver.executeScript("return Array.prototype.slice.call(document.getElementsByTagName('*'))" +
".map(function(el) {return [el, window.getComputedStyle(el).cssText];})", elements)
.then((styles: any) => {
//stuff would be done here with the styles
console.log(styles);
});
});
});
相关文章:
- 无法在通过jQuery的ajax加载的页面中执行javascript
- 在Safari执行javascript之前对其进行修改
- 如何在执行此特定onclick事件时执行JavaScript函数
- 如何在从浏览缓存加载页面时执行javascript
- 使用Rhino和ASE执行Javascript的区别
- 如何在加载完整页面后严格执行javascript代码
- 在动态加载的对话框中执行Javascript
- 在Sinatra中执行Javascript
- 通过AJAX加载页面并执行javascript和CSS
- 适用于多种浏览器的Selenium-需要能够执行javascript的webDriver
- 如何在seleniumwebdriver中执行javascript提示并等待接受输入
- 在window.open()生成的窗口中执行JavaScript
- AJAX成功回调-执行javascript时出现问题
- 通过指令在控制器中执行javascript函数
- 从React Native Android原生地执行JavaScript代码
- iframe未执行Javascript方法(PHP)
- 执行JavaScript代码,使用selenium webdriver或WatiN从控制台获取日志
- 通过web驱动程序异步执行Javascript
- 如何在长时间执行JavaScript期间显示微调器
- 点击困难时执行javascript函数