org.openqa.selenium.StaleElementReferenceException: stale elementreference: element is not attached

场景:用 Selenium 渲染页面后,有一个 Div 是通过 Ajax 渲染出来的,然后碰到了这个异常。

StackOverflow 上的答案,看了一部分,基本都是在说如果第一次拿不到,报了这个异常,则在 catch exception 的时候,再执行一次。 这样做大部分情况可能没问题,但是逻辑始终是有问题的。比如说就算执行两次,但是这两次执行的时间很快,而想要获取的元素此时仍然没有渲染出来怎么办?理论上这个概率挺大的。之所以很多人附议这个答案,我理解还是因为对爬虫的结果精度不那么高,所以有时候拿不到数据也是能容忍的。

本次讨论旨在如何解决这个问题上。这个问题的原因,上面已经说了,那做法理论上就是在元素加载完之后,再去执行 find 动作。selenium 有一个类叫 WebDriverWait,它有很多函数可以使用。

初始化

WebDriverWait wait = new WebDriverWait(driver, waitMillions);

第一个参数为当前的 WebDriver 对象,第二个是超时时间。超时时间的意义在于,如果开发者对当前页面的元素定位有误,也不会影响整个流程,只是会阻塞一段时间。

使用

wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(css)));

这是根据 css 选择器,选择元素

wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.cssSelector(css)))

这是根据 css 选择器,选择一批元素

叨一句

比如我们设置超时时间为 20 秒,那么我们在获取一个元素的时候,这个 20 秒是什么概念呢?

我们假设一个元素获取平均需要 1 秒(只是假设)

在获取这个元素之前,需要等待至少 3 秒(也只是假设,比如异步请求数据就是很慢)

那么正常来说,4秒之内元素渲染完毕了,还需不需要等 16 秒呢?不需要!如果4秒后元素渲染完毕,即执行 find,返回元素对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值