![](/img/trans.png)
[英]Twilio gather how can I tell gather wait for sometime before speech starts and start collecting
[英]How can I tell ChromeDriver to wait longer for Chrome to launch before giving up?
我正在使用Selenium和Python在Raspberry Pi 3上的Ubuntu MATE 16.04上的Chromium中自动显示和导航Chromium中的网站。(请考虑使用无人看管的数字标牌。)这种组合一直有效,直到今天最新版本的Chromium(具有匹配功能) ChromeDriver)通过自动更新安装。
由于Chromium在下一次启动时需要执行一些升级内务处理任务,因此它花费的时间比平常多一点。 请记住,它在Raspberry Pi上,因此I / O严重受到SD卡的瓶颈。 不幸的是,花了足够长的时间使我的Python脚本失败,因为ChromeDriver从一开始就放弃了Chromium:
Traceback (most recent call last):
File "call-tracker-start", line 15, in <module>
browser = webdriver.Chrome(executable_path=chromedriver_path, options=chrome_options)
File "/home/pi/.local/lib/python3.5/site-packages/selenium/webdriver/chrome/webdriver.py", line 75, in __init__
desired_capabilities=desired_capabilities)
File "/home/pi/.local/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 154, in __init__
self.start_session(desired_capabilities, browser_profile)
File "/home/pi/.local/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 243, in start_session
response = self.execute(Command.NEW_SESSION, parameters)
File "/home/pi/.local/lib/python3.5/site-packages/selenium/webdriver/remote/webdriver.py", line 312, in execute
self.error_handler.check_response(response)
File "/home/pi/.local/lib/python3.5/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: chrome not reachable
(Driver info: chromedriver=2.35 (0),platform=Linux 4.4.38-v7+ armv7l)
当然,当脚本在抛出此异常后死亡时,Chromium实例在完成其内务处理之前便被杀死,这意味着下次必须重新开始,因此它花费的时间与上次一样长,并且失败同样困难。
如果然后我手动干预并以普通用户身份运行Chromium,我只是……等一两分钟……让Chromium完成其升级内务处理,然后打开其浏览器窗口,然后我彻底退出应用程序。 现在,客房服务已经完成,Chromium下次将以更高的速度启动,因此我的Python脚本突然运行而没有任何错误,因为ChromeDriver看到Chromium在其可接受的超时窗口内完成了启动。
在下一次自动更新失败之前,一切都会很好,然后再次发生同样的问题。 我不想在每次更新后都必须手动进行干预,也不想禁用自动更新。
如何通知ChromeDriver在启动Chromium时不要这么快就放弃?
我寻找了可以设置的某种超时值,但在ChromeDriver或Selenium for Python文档中找不到任何值。
有趣的是, 有一个timeout
可以传递到火狐的webdriver,参数如图中硒的Python API文档 :
超时 –使用扩展连接时等待Firefox启动的时间。
此参数也在Internet Explorer WebDriver中列出,但在Chrome WebDriver API文档中却不存在。
我也不介意通过service_args
将某些内容直接传递给ChromeDriver,但是我在ChromeDriver文档中找不到任何相关选项。
在努力寻找一种方法来重现此问题以测试解决方案后,我能够指出Chromium在升级后永久启动的原因。
看来,作为升级后内部整理的一部分,Chromium会重建用户的字体缓存。 这是CPU和I / O密集型过程,在Raspberry Pi及其SD卡上特别困难,因此,每当需要重建字体缓存时,启动时间都将达到2.5分钟。
可以通过有意删除字体缓存来重现该问题,这将强制进行重建:
pi@rpi-dev1:~$ killall chromium-browser
pi@rpi-dev1:~$ time chromium-browser --headless --disable-gpu --dump-dom 'about:blank'
[0405/132706.970822:ERROR:gpu_process_transport_factory.cc(1019)] Lost UI shared context.
<html><head></head><body></body></html>
real 0m0.708s
user 0m0.340s
sys 0m0.200s
pi@rpi-dev1:~$ rm -Rf ~/.cache/fontconfig
pi@rpi-dev1:~$ time chromium-browser --headless --disable-gpu --dump-dom 'about:blank'
[0405/132720.917590:ERROR:gpu_process_transport_factory.cc(1019)] Lost UI shared context.
<html><head></head><body></body></html>
real 2m9.449s
user 2m8.670s
sys 0m0.590s
没错,没有选项可以明确设置初始驱动程序创建的timeout
。 我建议在这里访问他们的git页面并创建一个新问题。 如果您要在其中创建错误,它也具有指向直接ChromeDriver网站的链接。 目前,没有可以设置超时的选项。
您可以同时尝试类似的方法:
import webbrowser
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
try:
driver = webdriver.Chrome()
except WebDriverException:
webbrowser.open_new('http://www.Google.com')
# Let this try and get Chrome open, then go back and use webdriver
这是关于webbrowser的文档: https : //docs.python.org/3/library/webbrowser.html
根据您的问题,无需进行代码试用,就很难分析您所看到的错误背后的原因:
selenium.common.exceptions.WebDriverException: Message: chrome not reachable
也许有关正在使用的二进制文件的版本信息的更多详细信息会在某种程度上对我们有所帮助。
实际上 ,要求ChromeDriver等待更长的时间才能放弃启动Chrome ,这对我们无济于事,因为ChromeDriver的默认配置可以满足最佳需求。
但是,当二进制版本不兼容时, WebDriverException:消息:无法访问chrome是很常见的问题。 您可以在org.openqa.selenium.WebDriverException中找到有关此问题的详细讨论:chrome无法访问-尝试启动新会话时
事实证明,不仅Selenium没有timeout
选项可以传递给ChromeDriver,而且缺少重新编译自己的自定义ChromeDriver的能力,目前还无法以编程方式更改此值。 可悲的是, 查看源代码表明Google已将超时值硬编码为60秒!
std::unique_ptr<DevToolsHttpClient> client(new DevToolsHttpClient( address, context_getter, socket_factory, std::move(device_metrics), std::move(window_types), capabilities->page_load_strategy)); base::TimeTicks deadline = base::TimeTicks::Now() + base::TimeDelta::FromSeconds(60); Status status = client->Init(deadline - base::TimeTicks::Now());
在更改此代码以允许自定义截止日期之前,唯一的选择是解决方法。
我最终采取了一种在硒调用ChromeDriver之前“灌注”铬的方法。 这样一来,升级前的缓慢启动就不会影响ChromeDriver开始倒计时了。 @PixelEinstein给出的答案帮助我走了正确的路,但是此解决方案在两个方面有所不同:
webbrowser.open_new()
未被调用。 这是代码片段:
#!/usr/bin/env python3 import subprocess from selenium import webdriver some_site = 'http://www.google.com' chromedriver_path = '/usr/lib/chromium-browser/chromedriver' # Block until Chromium finishes launching and self-terminates subprocess.run(['chromium-browser', '--headless', '--disable-gpu', '--dump-dom', 'about:blank']) browser = webdriver.Chrome(executable_path=chromedriver_path) browser.get(some_site) # Continue on with your Selenium business...
在实例化webdriver.Chrome()
对象之前,这将等待Chromium完成升级后的内务处理,无论花费多长时间。 Chromium以无头模式启动,其中--dump-dom
是一次操作,将请求的网页(在本例中为about:blank
)写入stdout,该操作将被忽略。 完成该操作后,铬会自行终止,然后从subprocess.run()
调用返回,从而解除程序流。 之后,放心让ChromeDriver开始倒计时是安全的,因为Chromium将在几秒钟内启动。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.