TL; DR:始终使用明确的等待。 忘记隐含的等待存在。
以下是显式和隐式等待之间的区别的简要说明:
显式等待:
logging和定义的行为。
运行在selenium的本地部分(用你的代码语言)。
在任何你能想到的条件下工作。
返回成功或超时错误。
可以定义元素的缺失为成功的条件。
可以自定义重试和exception之间的延迟忽略。
隐含的等待:
没有证据和实际上未定义的行为。
运行在selenium的远程部分(控制浏览器的部分)。
只适用于查找元素的方法。
返回find的元素或(超时后)未find。
如果检查元素的缺失必须一直等到超时。
除全局超时之外无法自定义。
让我们看看selenium的实际源代码中显式等待和隐式等待的区别。 我从Python的python绑定中复制了代码,因为python“易于阅读”。
WebDriverWait.until()的代码(显式等待):
def until(self, method, message=''): end_time = time.time() + self._timeout while(True): try: value = method(self._driver) if value: return value except self._ignored_exceptions: pass time.sleep(self._poll) if(time.time() > end_time): break raise TimeoutException(message)
现在用人类语言:明确的等待期望一个方法,如果成功,返回一个真值。 然后重复执行给定的方法之间的延迟。 来自给定方法的预期错误得到抑制。 如果给定的方法返回一个真值,那么明确的等待将返回该值。 如果时间用完,则会引发超时exception。
比较WebDriver.implicitly_wait() (为简洁起见删除了注释WebDriver.implicitly_wait()的代码:
def implicitly_wait(self, time_to_wait): self.execute(Command.IMPLICIT_WAIT, {'ms': float(time_to_wait) * 1000})
self.execute()是WebDriver.execute() ,它调用RemoteConnection.execute() ,这反过来,据我所知,一个RPC到远程端的selenium。
用人类语言:隐含的等待发送一个消息到seleniumwebdriver的“远程端”。 selenium驱动程序的远程端是实际控制浏览器的selenium的一部分。 远程方对信息做了什么? “这取决于”。 这取决于操作系统,浏览器和selenium版本。 据我所知,不能保证具体实施的实际行为。
可能的实现是:
反复尝试查找元素,直到超时。 find元素后立即返回。
尝试find元素。 等到超时。 再试一次。
等到超时。 尝试find元素。
请注意,隐式等待仅在查找元素方法上生效。
我没有查到selenium远端的实际源代码。 这些信息是通过阅读关于selenium中隐式和显式等待的错误报告中的注释来收集的:
我的结论是:隐含的等待是不好的。 能力是有限的。 行为是没有文档和实现的依赖。
显式的等待可以做一切隐含的等待可以和更多。 显式等待的唯一缺点是由于多个远程过程调用而造成更多的开销。 明显的等待也稍微冗长些。 但是这种冗长使得代码是明确的。 隐含的更好。 对?
进一步阅读: