我有一个应用程序,需要一个长时间运行的Selenium Web驱动程序示例(我使用Chrome driver 83.0.4103.39在无头模式).基本上应用程序不断拉取url数据从一个队列,并把提取的url给Selenium应该执行一些分析网站.许多这些网站可能会关闭,无法访问或损坏,因此我设置了10秒页面加载超时,以避免Selenium永远等待页面加载。
这里的问题是在执行一段时间后(比如说10分钟)Selenium开始对每个url给予Timed out receiving message from renderer
错误,最初它工作正常,正确打开好的网站,对坏的网站超时(网站无法加载),但一段时间后,它开始给予超时的一切,甚至网站,应该正确打开(我已经检查过了,它们在Chrome浏览器上可以正确打开)。我很难调试这个问题,因为应用程序中的每个异常都被正确捕获。我还注意到这个问题只发生在headless
模式下。
- 最新情况 *
在网站分析过程中,我还需要考虑iframe(仅顶层),因此我还添加了一个逻辑来将驱动程序上下文切换到主页中的每个iframe,并提取相关的html。
这是应用程序的简化版本:
import traceback
from time import sleep
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
width = 1024
height = 768
chrome_options = Options()
chrome_options.page_load_strategy = 'normal'
chrome_options.add_argument('--enable-automation')
chrome_options.add_argument('disable-infobars')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--lang=en')
chrome_options.add_argument('--ignore-certificate-errors')
chrome_options.add_argument('--allow-insecure-localhost')
chrome_options.add_argument('--allow-running-insecure-content')
chrome_options.add_argument('--disable-notifications')
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('--disable-browser-side-navigation')
chrome_options.add_argument('--mute-audio')
chrome_options.add_argument('--headless')
chrome_options.add_argument('--force-device-scale-factor=1')
chrome_options.add_argument(f'window-size={width}x{height}')
chrome_options.add_experimental_option(
'prefs', {
'intl.accept_languages': 'en,en_US',
'download.prompt_for_download': False,
'download.default_directory': '/dev/null',
'automatic_downloads': 2,
'download_restrictions': 3,
'notifications': 2,
'media_stream': 2,
'media_stream_mic': 2,
'media_stream_camera': 2,
'durable_storage': 2,
}
)
driver = webdriver.Chrome(options=options)
driver.set_page_load_timeout(10) # Timeout 10 seconds
# Polling queue
while True:
url = queue.pop()
# Try open url
try:
driver.get(url)
except BaseException as e:
print(e)
print(traceback.format_exc())
continue
# Take website screenshot
png = driver.get_screenshot_as_png()
# Extract html from iframes (if any)
htmls = [driver.page_source]
iframes = driver.find_elements_by_xpath("//iframe")
for index, iframe in enumerate(iframes):
try:
driver.switch_to.frame(index)
htmls.append(driver.page_source)
driver.switch_to.default_content()
except BaseException as e:
print(e)
print(traceback.format_exc())
continue
# Do some analysis
for html in htmls:
# ...
pass
# Wait a bit
sleep(0.1)
以下是堆栈跟踪的示例:
Opening https://www.yourmechanic.com/user/appointment/3732777/?access_token=HLZYIg&ukey=6quWpg1724633&rcode=abttgi&utm_medium=sms&utm_source= rb
LOAD EXCEPTION Message: timeout: Timed out receiving message from renderer: 10.000
(Session info: headless chrome=83.0.4103.116)
Traceback (most recent call last):
File "/Users/macbmacbookpro4ookpro4/Documents/Projects/python/proj001/main.py", line 202, in inference
driver.get(url)
File "/opt/anaconda3/envs/cv/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 333, in get
self.execute(Command.GET, {'url': url})
File "/opt/anaconda3/envs/cv/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/opt/anaconda3/envs/cv/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message: timeout: Timed out receiving message from renderer: 10.000
(Session info: headless chrome=83.0.4103.116)
有人知道为什么在正确执行一段时间后,Selenium开始为它试图打开的任何URL给予超时异常吗?
1条答案
按热度按时间jm81lzqq1#
此错误消息...
...表示 * ChromeDriver * 无法与 * 浏览上下文 *(即 * Chrome浏览器 * 会话)通信。
深入探讨
出现此错误的原因有多种。其中一些原因和补救措施如下:
disable-infobars
和--enable-automation
几乎是 * 类似的 *,并且不再保留disable-infobars
。--enable-automation
将满足您的目的。因此,您需要删除:您可以在Chromev76中的无法隐藏"Chrome正由自动化软件控制"信息栏中找到详细讨论
--enable-automation
仍然是experimental_option
,因此您需要:您可以在如何通过Selenium IDE中使用FirefoxDriver的选项来使用setExperimentalOption中找到详细的讨论?
--enable-automation
,则还需要使用useAutomationExtension
:--disable-gpu
,因此需要删除:你可以在Python Selenium中的Chrome选项中找到详细的讨论:禁用GPU与无外设
{width}x{height}
,例如1920, 1080
有关详细讨论,请参阅如何在Selenium Chrome Python中设置窗口大小
chrome_options.add_argument('--headless')
,您需要使用headless
属性,如下所示:您可以在如何配置ChromeDriver以通过Selenium在Headless模式下启动Chrome浏览器中找到详细讨论?
<iframe>
/<frame>
执行switch_to
操作,因为其中一些元素可能将 * style * 属性值设置为**display: none;
**。您可以在预期条件失败中找到详细讨论:正在等待可单击的元素,以获取包含style ="display:无;"
frame to be available and switch to it()
,如下所示:您可以在以下位置找到一些相关讨论:
参考文献
您可以在以下位置找到一些关于Timed out receiving message from renderer的相关详细讨论: