热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何在初始化seleniumwebdriver时修复pythonselenium错误“连接被拒绝”?

我在非公共网页上运行非常复杂的python-selenium测试.在大多数情况下,这些测试运行良好,但有时其中一个测试在webdriver本身初始化期间失败.提示:尝试初始化web

我在非公共网页上运行非常复杂的python-selenium测试.在大多数情况下,这些测试运行良好,但有时其中一个测试在webdriver本身初始化期间失败.

提示:尝试初始化webdriver时会发生此错误,即执行以下操作时:

# Start of the tests
mydriver = webdriver.Firefox(firefox_profile=profile, log_path=logfile)
# ERROR HAPPENS HERE
# Doing other stuff here
....
# Doing tests here
....
# Doing shutdown here
mydriver.quit()

以下是此类错误的完整示例:

___________ ERROR at setup of TestSuite.test_synaptic_events_fitting ___________
> lambda: ihook(item=item, **kwds),
when=when,
)
/usr/local/lib/python2.7/dist-packages/flaky/flaky_pytest_plugin.py:273:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
conftest.py:157: in basedriver
mydriver = firefox.get_driver(*args)
bsp_usecase_tests/tools/firefox.py:44: in get_driver
driver = webdriver.Firefox(firefox_profile=profile, log_path=logfile) #### INITIALIZING OF WEBDRIVER HERE
/usr/local/lib/python2.7/dist-packages/selenium/webdriver/firefox/webdriver.py:158: in __init__
keep_alive=True)
/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py:154: in __init__
self.start_session(desired_capabilities, browser_profile)
/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py:243: in start_session
respOnse= self.execute(Command.NEW_SESSION, parameters)
/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py:311: in execute
self.error_handler.check_response(response)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self =
respOnse= {'status': 500, 'value': '{"value":{"error":"unknown error","message":"connection refused","stacktrace":"stack backtra...s::imp::thread::{{impl}}::new::thread_start\n at /checkout/src/libstd/sys/unix/thread.rs:84"}}'}
def check_response(self, response):
"""
Checks that a JSON response from the WebDriver does not have an error.
:Args:
- response - The JSON response from the WebDriver server as a dictionary
object.
:Raises: If the response contains an error message.
"""
status = response.get('status', None)
if status is None or status == ErrorCode.SUCCESS:
return
value = None
message = response.get("message", "")
screen = response.get("screen", "")
stacktrace = None
if isinstance(status, int):
value_json = response.get('value', None)
if value_json and isinstance(value_json, basestring):import jsontry: value = json.loads(value_json) if len(value.keys()) == 1: value = value['value'] status = value.get('error', None) if status is None: status = value["status"] message = value["value"] if not isinstance(message, basestring): value = message message = message.get('message') else: message = value.get('message', None)except ValueError: pass
exception_class = ErrorInResponseException
if status in ErrorCode.NO_SUCH_ELEMENT:
exception_class = NoSuchElementException
elif status in ErrorCode.NO_SUCH_FRAME:
exception_class = NoSuchFrameException
elif status in ErrorCode.NO_SUCH_WINDOW:
exception_class = NoSuchWindowException
elif status in ErrorCode.STALE_ELEMENT_REFERENCE:
exception_class = StaleElementReferenceException
elif status in ErrorCode.ELEMENT_NOT_VISIBLE:
exception_class = ElementNotVisibleException
elif status in ErrorCode.INVALID_ELEMENT_STATE:
exception_class = InvalidElementStateException
elif status in ErrorCode.INVALID_SELECTOR \or status in ErrorCode.INVALID_XPATH_SELECTOR \or status in ErrorCode.INVALID_XPATH_SELECTOR_RETURN_TYPER:
exception_class = InvalidSelectorException
elif status in ErrorCode.ELEMENT_IS_NOT_SELECTABLE:
exception_class = ElementNotSelectableException
elif status in ErrorCode.ELEMENT_NOT_INTERACTABLE:
exception_class = ElementNotInteractableException
elif status in ErrorCode.INVALID_COOKIE_DOMAIN:
exception_class = InvalidCOOKIEDomainException
elif status in ErrorCode.UNABLE_TO_SET_COOKIE:
exception_class = UnableToSetCOOKIEException
elif status in ErrorCode.TIMEOUT:
exception_class = TimeoutException
elif status in ErrorCode.SCRIPT_TIMEOUT:
exception_class = TimeoutException
elif status in ErrorCode.UNKNOWN_ERROR:
exception_class = WebDriverException
elif status in ErrorCode.UNEXPECTED_ALERT_OPEN:
exception_class = UnexpectedAlertPresentException
elif status in ErrorCode.NO_ALERT_OPEN:
exception_class = NoAlertPresentException
elif status in ErrorCode.IME_NOT_AVAILABLE:
exception_class = ImeNotAvailableException
elif status in ErrorCode.IME_ENGINE_ACTIVATION_FAILED:
exception_class = ImeActivationFailedException
elif status in ErrorCode.MOVE_TARGET_OUT_OF_BOUNDS:
exception_class = MoveTargetOutOfBoundsException
elif status in ErrorCode.Javascript_ERROR:
exception_class = JavascriptException
elif status in ErrorCode.SESSION_NOT_CREATED:
exception_class = SessionNotCreatedException
elif status in ErrorCode.INVALID_ARGUMENT:
exception_class = InvalidArgumentException
elif status in ErrorCode.NO_SUCH_COOKIE:
exception_class = NoSuchCOOKIEException
elif status in ErrorCode.UNABLE_TO_CAPTURE_SCREEN:
exception_class = ScreenshotException
elif status in ErrorCode.ELEMENT_CLICK_INTERCEPTED:
exception_class = ElementClickInterceptedException
elif status in ErrorCode.INSECURE_CERTIFICATE:
exception_class = InsecureCertificateException
elif status in ErrorCode.INVALID_COORDINATES:
exception_class = InvalidCoordinatesException
elif status in ErrorCode.INVALID_SESSION_ID:
exception_class = InvalidSessionIdException
elif status in ErrorCode.UNKNOWN_METHOD:
exception_class = UnknownMethodException
else:
exception_class = WebDriverException
if value == '' or value is None:
value = response['value']
if isinstance(value, basestring):
if exception_class == ErrorInResponseException:raise exception_class(response, value)
raise exception_class(value)
if message == "" and 'message' in value:
message = value['message']
screen = None
if 'screen' in value:
screen = value['screen']
stacktrace = None
if 'stackTrace' in value and value['stackTrace']:
stacktrace = []
try:for frame in value['stackTrace']: line = self._value_or_default(frame, 'lineNumber', '') file = self._value_or_default(frame, 'fileName', '') if line: file = "%s:%s" % (file, line) meth = self._value_or_default(frame, 'methodName', '') if 'className' in frame: meth = "%s.%s" % (frame['className'], meth) msg = " at %s (%s)" msg = msg % (meth, file) stacktrace.append(msg)
except TypeError:pass
if exception_class == ErrorInResponseException:
raise exception_class(response, message)
elif exception_class == UnexpectedAlertPresentException and 'alert' in value:
raise exception_class(message, screen, stacktrace, value['alert'].get('text'))
> raise exception_class(message, screen, stacktrace)
E WebDriverException: Message: connection refused
/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/errorhandler.py:237: WebDriverException

这些测试作为docker容器内jenkins计划的一部分运行,以确保始终保持完全相同的环境.以下是使用过的软件包及其版本的列表:

> python 2.7.12
> pytest 3.6.1
>硒3.8.0
> geckodriver 0.19.1
> firefox 62.0
>片状3.4.0

该错误大致出现在所有测试的约1%中.大约有15种不同的测试,错误似乎是随机出现的(即并不总是相同的测试).

这是firefox / selenium / geckodriver中的错误吗?有没有办法解决这个问题?

以下代码片段不是我正在使用的一些代码!这只是如何解决上述问题的想法.这可能是解决我原来问题的好方法吗?

while counter<5:
try:
webdriver = webdriver.Firefox(firefox_profile=profile, log_path=logfile)
break
except WebDriverException:
counter +=1

有一个更好的方法吗?

解决方法:

此错误消息…

{'status': 500, 'value': '{"value":{"error":"unknown error","message":"connection refused","stacktrace":"stack backtra...s::imp::thread::{{impl}}::new::thread_start\n at /checkout/src/libstd/sys/unix/thread.rs:84"}}'}

…暗示GeckoDriver无法启动/生成新的WebBrowsing会话,即Firefox浏览器会话.

在comment讨论中,0700 @andreastt提到:

geckodriver is implicitly ending the (previous) session when the last window closes. If driver.quit() is called as the subsequent command it will fail because the session has already been implicitly deleted.

In these cases GeckoDriver should detect that the session has been closed implicitly after driver.close() or ignore the response from driver.quit() in case the session has already been closed.

在这种情况下,会生成以下跟踪日志:

1505753594121 webdriver::server DEBUG Last window was closed, deleting session
1505753594121 webdriver::server DEBUG Deleting session
1505753594121 geckodriver::marionette DEBUG Stopping browser process
1505753594364 webdriver::server DEBUG <- 200 OK {"value": []}
1505753594523 webdriver::server DEBUG -> DELETE /session/a8312282-af00-4931-94d4-0d401abf01c9
1505753594524 webdriver::server DEBUG <- 500 Internal Server Error {"value":{"error":"session not created","message":"Tried to run command without establishing a connection","stacktrace":"stack backtrace:\n 0: 0x4f388c - backtrace::backtrace::trace::h736111741fa0878e\n 1: 0x4f38c2 - backtrace::capture::Backtrace::new::h63b8a5c0787510c9\n 2: 0x442c61 - webdriver::error::WebDriverError::new::hc4fe6a1ced4e57dd\n 3: 0x42a926 - >::run::hba9181b5aacf8f04\n 4: 0x402c59 - std::sys_common::backtrace::__rust_begin_short_backtrace::h19de262639927233\n 5: 0x40c065 - std::panicking::try::do_call::h6c1659fc4d01af51\n 6: 0x5e38ec - panic_unwind::__rust_maybe_catch_panic\n at /checkout/src/libpanic_unwind/lib.rs:98\n 7: 0x420d32 - >::call_box::h953e5f59694972c5\n 8: 0x5dc00b - alloc::boxed::{{impl}}::call_once<(),()>\n at /checkout/src/liballoc/boxed.rs:661\n - std::sys_common::thread::start_thread\n at /checkout/src/libstd/sys_common/thread.rs:21\n - std::sys::imp::thread::{{impl}}::new::thread_start\n at /checkout/src/libstd/sys/unix/thread.rs:84"}}
1505753594533 webdriver::server DEBUG -> DELETE /session/a8312282-af00-4931-94d4-0d401abf01c9
1505753594542 webdriver::server DEBUG <- 500 Internal Server Error {"value":{"error":"session not created","message":"Tried to run command without establishing a connection","stacktrace":"stack backtrace:\n 0: 0x4f388c - backtrace::backtrace::trace::h736111741fa0878e\n 1: 0x4f38c2 - backtrace::capture::Backtrace::new::h63b8a5c0787510c9\n 2: 0x442c61 - webdriver::error::WebDriverError::new::hc4fe6a1ced4e57dd\n 3: 0x42a926 - >::run::hba9181b5aacf8f04\n 4: 0x402c59 - std::sys_common::backtrace::__rust_begin_short_backtrace::h19de262639927233\n 5: 0x40c065 - std::panicking::try::do_call::h6c1659fc4d01af51\n 6: 0x5e38ec - panic_unwind::__rust_maybe_catch_panic\n at /checkout/src/libpanic_unwind/lib.rs:98\n 7: 0x420d32 - >::call_box::h953e5f59694972c5\n 8: 0x5dc00b - alloc::boxed::{{impl}}::call_once<(),()>\n at /checkout/src/liballoc/boxed.rs:661\n - std::sys_common::thread::start_thread\n at /checkout/src/libstd/sys_common/thread.rs:21\n - std::sys::imp::thread::{{impl}}::new::thread_start\n at /checkout/src/libstd/sys/unix/thread.rs:84"}}
1505753594549 webdriver::server DEBUG -> GET /shutdown
1505753594551 webdriver::server DEBUG <- 404 Not Found {"value":{"error":"unknown command","message":"GET /shutdown did not match a known command","stacktrace":"stack backtrace:\n 0: 0x4f388c - backtrace::backtrace::trace::h736111741fa0878e\n 1: 0x4f38c2 - backtrace::capture::Backtrace::new::h63b8a5c0787510c9\n 2: 0x442d88 - webdriver::error::WebDriverError::new::hea6d4dbf778b2b24\n 3: 0x43c65f - as hyper::server::Handler>::handle::hd03629bd67672697\n 4: 0x403a04 - std::sys_common::backtrace::__rust_begin_short_backtrace::h32e6ff325c0d7f46\n 5: 0x40c036 - std::panicking::try::do_call::h5f902dc1eea01ffe\n 6: 0x5e38ec - panic_unwind::__rust_maybe_catch_panic\n at /checkout/src/libpanic_unwind/lib.rs:98\n 7: 0x4209a2 - >::call_box::h032bafb4b576d1cd\n 8: 0x5dc00b - alloc::boxed::{{impl}}::call_once<(),()>\n

虽然您看到的错误的错误代码是“status”:500,我提供的错误示例是404 Not Found,显然看起来不同,核心原因类似于:

"message":"connection refused"

由于:

imp::thread::{{impl}}::new::thread_start

从:

/checkout/src/libstd/sys/unix/thread.rs:84

从另一个角度来看,当您使用GeckoDriver时,Selenium和Firefox确保二进制文件兼容如下:

分析

自geckodriver 0.19.1的可用性以来,geckodriver二进制文件发生了重大变化.一些变化是:

> GeckoDriver v0.22.0(2018-09-15):

>用于[脚本超时]和[超时]错误的HTTP状态代码已从请求超时(408)更改为内部服务器错误(500),以便不破坏HTTP / 1.1 Keep-Alive支持,因为HTTP客户端解释旧的状态代码表示他们应该复制请求.
>持久连接的HTTP / 1.1 Keep-Alive超时已增加到90秒.
>当没有活动会话时,现在返回[无效会话ID]错误.
>当geckodriver连接到Marionette时,握手已经通过杀死Firefox进程失败而得到了强化.
>握手读取超时已减少到10秒而不是永远等待.

> GeckoDriver v0.21.0(2018-06-15):

>现在没有返回值的WebDriver命令正确返回{value:null}而不是空字典.
>强制使用IPv4网络堆栈.
>

On certain system configurations, where localhost resolves to an IPv6 address, geckodriver would attempt to connect to Firefox on the wrong IP stack, causing the connection attempt to time out after 60 seconds. We now ensure that geckodriver uses IPv4 consistently to both connect to Firefox and for allocating a free port.

> GeckoDriver v0.20.1(2018-04-06):

>避免尝试杀死已停止的Firefox进程.
>

With the change to allow Firefox enough time to shut down in 0.20.0, geckodriver started unconditionally killing the process to reap its exit status. This caused geckodriver to inaccurately report a successful Firefox shutdown as a failure.

> GeckoDriver v0.20.0(2018-03-08):

>来自geckodriver的Backtraces不再替代缺少的Marionette堆栈跟踪.
> Firefox进程现在有足够的时间关闭,允许有足够的时间让Firefox关闭挂起监视器启动.
>

Firefox has an integrated background monitor that observes long-running threads during shutdown. These threads will be killed after 63 seconds in the event of a hang. To allow Firefox to shut down these threads on its own, geckodriver has to wait that time and some additional seconds.

>将Selenium升级到当前级别Version 3.14.0.
>将GeckoDriver升级到GeckoDriver v0.22.0级别.
>将Firefox版本升级到Firefox v62.0.2级别.
>如果您的基本Web客户端版本太旧,请通过Revo Uninstaller将其卸载并安装最新的GA和已发布的Web客户端版本.
>始终在tearDown(){}方法中调用driver.quit()来关闭&正常销毁WebDriver和Web Client实例.
>以非root用户身份执行测试.

更新

根据您的问题更新-wig,您可以为多个试验引发循环,以初始化selenium webdriver实例,如下所示:

>通过调用taskkill命令(特定于WindowsOS)确保没有悬挂式geckodriver实例,如下所示:

os.system("taskkill /f /im geckodriver.exe /T")

>通过调用kill()命令(跨平台)确保没有悬挂式geckodriver实例,如下所示:

from selenium import webdriver
import psutil
from selenium.common.exceptions import WebDriverException
for counter in range(5):
try:
webdriver = webdriver.Firefox(executable_path=r'C:\Utility\BrowserDrivers\geckodriver.exe')
print("WebDriver and WebBrowser initialized ...")
break
except WebDriverException:
#Cross platform
PROCNAME = "geckodriver"
for proc in psutil.process_iter():
# check whether the process name matches
if proc.name() == PROCNAME:proc.kill()
print("Retrying ...")
print("Out of loop ...")


推荐阅读
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • 解决JAX-WS动态客户端工厂弃用问题并迁移到XFire
    在处理Java项目中的JAR包冲突时,我们遇到了JaxWsDynamicClientFactory被弃用的问题,并成功将其迁移到org.codehaus.xfire.client。本文详细介绍了这一过程及解决方案。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • 使用Vultr云服务器和Namesilo域名搭建个人网站
    本文详细介绍了如何通过Vultr云服务器和Namesilo域名搭建一个功能齐全的个人网站,包括购买、配置服务器以及绑定域名的具体步骤。文章还提供了详细的命令行操作指南,帮助读者顺利完成建站过程。 ... [详细]
  • 本文介绍如何使用阿里云的fastjson库解析包含时间戳、IP地址和参数等信息的JSON格式文本,并进行数据处理和保存。 ... [详细]
  • andr ... [详细]
  • Yii 实现阿里云短信发送 ... [详细]
  • 本文总结了在使用Ionic 5进行Android平台APK打包时遇到的问题,特别是针对QRScanner插件的改造。通过详细分析和提供具体的解决方法,帮助开发者顺利打包并优化应用性能。 ... [详细]
  • 将Web服务部署到Tomcat
    本文介绍了如何在JDeveloper 12c中创建一个Java项目,并将其打包为Web服务,然后部署到Tomcat服务器。内容涵盖从项目创建、编写Web服务代码、配置相关XML文件到最终的本地部署和验证。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文详细介绍了Java中org.w3c.dom.Text类的splitText()方法,通过多个代码示例展示了其实际应用。该方法用于将文本节点在指定位置拆分为两个节点,并保持在文档树中。 ... [详细]
  • 本文详细介绍了Java中的访问器(getter)和修改器(setter),探讨了它们在保护数据完整性、增强代码可维护性方面的重要作用。通过具体示例,展示了如何正确使用这些方法来控制类属性的访问和更新。 ... [详细]
author-avatar
欣然沐羽民_699
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有