所以我使用的是Selenium的JavaScript实现,WebDriverJS。与任何Web浏览器自动化一样,最大的障碍是让代码减慢足够长的时间以加载页面元素。我的解决方案是:
对于我想要与之交互的每个元素,我有一个像这样的代码块
xpath = "//div[@id='gs_lc0']/input[@id='gbqfq']"
driver.wait(function(){
return waitForElement(xPath,driver);
});
try{
element = driver.findElement(webdriver.By.xpath(xPath));
}catch(e){
console.log("Wait Function False Positive")
}
element.sendKeys("Let Me Google That For You\n";
将此作为在等待函数中重复的函数
var waitForElement = function(path, driver){
console.log("try: " + path)
try{
driver.findElement(webdriver.By.xpath(path));
}catch (e){
console.log("FAILURE")
return false;
}
console.log("SUCCESS")
return true;
}
现在这段代码有时会起作用,但不会有其他代码。我觉得等待功能完全不起作用,我只是获得了幸运的网页加载时间。因此,为了测试这个理论,我将try函数添加到代码块中,甚至无法捕获“NoSuchElementError”。所以我的问题首当其冲的是,是否有其他方法来形成tryCatch函数,以便捕获这些错误。
如果想要完整再现,我的代码头部也是如此
var webdriver = require('selenium-webdriver'), element
var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();
driver.get('google.com');
答案 0 :(得分:13)
bagelmaker建议使用findElements
并不是坏事。当我想检查一个元素是否存在而不是混淆异常时,我通常会这样做。
但是,为了完整起见,以下是您处理元素不存在时生成的错误的方法:
var webdriver = require('selenium-webdriver');
var driver = new webdriver.Builder().
withCapabilities(webdriver.Capabilities.chrome()).
build();
driver.get('http://www.google.com');
driver.findElement(webdriver.By.id("fofofo")).then(null, function (err) {
if (err.name === "NoSuchElementError")
console.log("Element was missing!");
});
driver.quit();
then
的第二个参数是一个errback,如果findElement
失败则会调用它。因为selenium-webdriver
以promises运行,所以这就是你必须捕获错误的方法。使用try...catch
无法正常工作,因为Selenium无法立即开始工作;你问Selenium与findElement
有关的工作将在未来的某个不确定的时间进行。到那时,JavaScript执行已经移出try...catch
。
上面的代码搜索id
值为fofofo
的元素,该元素不存在且失败。
答案 1 :(得分:1)
我建议您阅读explicit and implicit waits。总结,显式等待将轮询网站,直到填充特定条件,而隐式等待更通用,并将等待指定的时间段来执行命令。在你的情况下,我会参考这个previous question,它通过使用:
解决driver.wait(function() {
return driver.findElement(webdriver.By.xpath(xPath)).isDisplayed();
}, timeout);
或强>
driver.wait(function() {
return driver.isElementPresent(locator);
}, timeout);
如果您需要澄清,请发表评论。
修改强>
我误解了这个问题。捕获NoSuchElementError的另一种方法是使用记录为here的方法findElements
,并具有示例实现here。如果不存在任何元素,它将返回大小为0的列表。这样,不会抛出异常,您可以根据列表的大小确定它是否存在。
我希望这是你问题的更好答案。
答案 2 :(得分:0)
您还可以在链式“catch”方法中捕获该错误:
driver.findElement(webdriver.By.id("fofofo")).then(() => {
// do some task
}).catch((e) => {
if(e.name === 'NoSuchElementError') {
console.log('Element not found');
}
})