关于 selenium 通过 JS 脚本的方式打开新窗口提示错误的问题

如何利用selenium且不通过运行js脚本的方式传递url并在新窗口或者标签打开它。
利用window.open(‘url’),运行不了,并且提示

urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='127.0.0.1', port=51483): Max retries exceeded with url: /session/1f2311de-3086-4a15-be02-e3d6d6308a58/element (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x000001758103C880>: 
Failed to establish a new connection: [WinError 10061] 由于目标计算机积极拒绝,无法连接。'))

写了个小的demo测试,发现都存在这个问题

from selenium import webdriver

driver = webdriver.Ie()
driver.get('http://www.baidu.com')
newwindow = 'window.open("https://www.google.com")'
driver.execute_script(newwindow)
driver.switch_to_window(driver.window_handles[1])
driver.close()
driver.switch_to_window(driver.window_handles[0])

仍旧提示以下错误

Traceback (most recent call last):
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\urllib3\connectionpool.py", line 665, in urlopen      
    httplib_response = self._make_request(
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\urllib3\connectionpool.py", line 421, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\urllib3\connectionpool.py", line 416, in _make_request
    httplib_response = conn.getresponse()
  File "c:\users\a\appdata\local\programs\python\python38\lib\http\client.py", line 1322, in getresponse
    response.begin()
  File "c:\users\a\appdata\local\programs\python\python38\lib\http\client.py", line 303, in begin       
    version, status, reason = self._read_status()
  File "c:\users\a\appdata\local\programs\python\python38\lib\http\client.py", line 264, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "c:\users\a\appdata\local\programs\python\python38\lib\socket.py", line 669, in readinto
    return self._sock.recv_into(b)
ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接。
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "e:\Dropbox\17.Develop\5.Project\autozboa\run.py", line 22, in <module>
    manage()
  File "e:\Dropbox\17.Develop\5.Project\autozboa\run.py", line 14, in manage
    m.handle_doc()  # 处理单个文件
  File "e:\Dropbox\17.Develop\5.Project\autozboa\manage.py", line 67, in handle_doc
    docs_unid = docs.get_docs_unid()
  File "e:\Dropbox\17.Develop\5.Project\autozboa\zboa\pages\docs_page.py", line 38, in get_docs_unid
    for doc in self.find_elements(*self.docs_link):
  File "e:\Dropbox\17.Develop\5.Project\autozboa\zboa\framework\base_page.py", line 70, in find_elements
    elements = self.driver.find_elements(*selector)
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 1005, in find_elements
    return self.execute(Command.FIND_ELEMENTS, {
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 319, in execute       
    response = self.command_executor.execute(driver_command, params)
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\selenium\webdriver\remote\remote_connection.py", line 374, in execute
    return self._request(command_info[0], url, body=data)
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\selenium\webdriver\remote\remote_connection.py", line 402, in _request
    resp = http.request(method, url, body=body, headers=headers)
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\urllib3\request.py", line 79, in request
    return self.request_encode_body(
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\urllib3\request.py", line 171, in request_encode_body
    return self.urlopen(method, url, **extra_kw)
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\urllib3\poolmanager.py", line 330, in urlopen
    response = conn.urlopen(method, u.request_uri, **kw)
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\urllib3\connectionpool.py", line 719, in urlopen
    retries = retries.increment(
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\urllib3\util\retry.py", line 400, in increment
    raise six.reraise(type(error), error, _stacktrace)
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\urllib3\packages\six.py", line 734, in reraise
    raise value.with_traceback(tb)
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\urllib3\connectionpool.py", line 665, in urlopen
    httplib_response = self._make_request(
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\urllib3\connectionpool.py", line 421, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "E:\Dropbox\17.Develop\5.Project\autozboa\env\lib\site-packages\urllib3\connectionpool.py", line 416, in _make_request
    httplib_response = conn.getresponse()
  File "c:\users\a\appdata\local\programs\python\python38\lib\http\client.py", line 1322, in getresponse
    response.begin()
  File "c:\users\a\appdata\local\programs\python\python38\lib\http\client.py", line 303, in begin
    version, status, reason = self._read_status()
  File "c:\users\a\appdata\local\programs\python\python38\lib\http\client.py", line 264, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
  File "c:\users\a\appdata\local\programs\python\python38\lib\socket.py", line 669, in readinto
    return self._sock.recv_into(b)
urllib3.exceptions.ProtocolError: ('Connection aborted.', ConnectionResetError(10054, '远程主机强迫关闭了一个现有的连接。', None, 10054, None))

希望大家给出出主意,该如何解决?

讨论数量: 36
Jason990420

一句一句执行, 看这两个错误是何时发生的 ?

第二个是在d.execute_script(newwindow)

那第一个呢 ?

4年前 评论
joeyun (楼主) 4年前

请问得到切确的解决方法了吗?救命!我也遇到了一样的问题。

2年前 评论
Jason990420

目前只能建议重新安装 Python, 这样可以去掉一些旧的安装

4年前 评论
Jason990420

Just install Python 3.8.1, Selenium 3.141.0, urllib3 1.25.8

It still working for me…..

4年前 评论
joeyun (楼主) 4年前
joeyun (楼主) 4年前
Jason990420

我又跑了一次demo, 发现 handles 内的顺序不是一定的, 所以切换视窗不能简单的以索引来调用

handles = driver.window_handles
parent_handle = driver.current_window_handle
index = 0 if handles[0] != parent_handle else 1
driver.switch_to.window(driver.window_handles[index])
4年前 评论
Jason990420

打印了两个之后就出错了....

以下步骤中间必须停下来, 确认browser已经作完动作.

from selenium import webdriver
d = webdriver.Ie('IEDriverServer.exe')

会出错吗?

print(d.window_handles)

会出错吗?

d.get('http://www.baidu.com')

出错吗?

打印了两个之后就出错了....问题不在 d.execute_script (newwindow)

有了新的进展, 然后呢? nothing ??

你可以自分析一下情况, 行吗? 再提供更多的讯息...... 很显然这与你Python的工作环境有关, 如果你没有自己捞出一些讯息, 别人是帮不了你的.

while not_OK():
    If condition1:    # you must go to find any condition different when you run your script.
        do_something_by_yourself_1()
    if conidtion2:
        do_something_by_yourself_2()
    if condition not in [condition1, condition2]
        get_help()

最笨的方法

  1. 移除 Python 3.8.1 (我也有些包不能用, 再回到3.7.6)
  2. 移除 Python 留下的痕迹, 比如 Python 目录, 安装的包, 安装包的缓存等等
  3. 重装 Python 3.7.6
  4. 重装 Selenium
  5. 重装 IE 11? 你的 IE 是什么版本?
4年前 评论
joeyun (楼主) 4年前
Jason990420
Internet Explorer 11
版本: 11.719.18362.0
IEDriverServer.exe
Command line server for the IE driver
Selenium WebDriver
version: 1.150.1.0
IEDriverServer64.exe
Command line server for the IE driver
Selenium WebDriver
version: 1.150.1.0
4年前 评论
joeyun (楼主) 4年前
joeyun (楼主) 4年前
Jason990420 (作者) 4年前
joeyun (楼主) 4年前
Jason990420

看了一下过程, 很可能是还没完全载入百度网页, 就作了下一步, 所以连接关闭了.

driver.get方法将导航到URL给定的页面. WebDriver将等待页面完全加载(即, 已触发"onload"事件), 然后再将控制权返回给测试或脚本. 值得注意的是,如果您的页面在加载时使用了很多AJAX,则WebDriver可能不知道何时已完全加载完毕.

也许你要等网页完全加载完毕,才能进行下一步.

不过我的执行环境没有这个问题,可能还是版本问题, 比如你的Python內建的 http包socket.py 和我的就不一樣.

>>> urllib3.__version__
'1.25.8'
>>> sys.version
'3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)]'

当然啦,还可能有一个问题,是你的宽带不穩定....

d:\>ping -n 277504 www.baidu.com

Ping www.wshifen.com [103.235.46.39] (使用 32 位元組的資料):
回覆自 103.235.46.39: 位元組=32 時間=95ms TTL=46
回覆自 103.235.46.39: 位元組=32 時間=76ms TTL=46
回覆自 103.235.46.39: 位元組=32 時間=99ms TTL=46
回覆自 103.235.46.39: 位元組=32 時間=92ms TTL=46
回覆自 103.235.46.39: 位元組=32 時間=80ms TTL=46
回覆自 103.235.46.39: 位元組=32 時間=83ms TTL=46
回覆自 103.235.46.39: 位元組=32 時間=92ms TTL=46
回覆自 103.235.46.39: 位元組=32 時間=94ms TTL=46
回覆自 103.235.46.39: 位元組=32 時間=79ms TTL=46
回覆自 103.235.46.39: 位元組=32 時間=88ms TTL=46
回覆自 103.235.46.39: 位元組=32 時間=101ms TTL=46
回覆自 103.235.46.39: 位元組=32 時間=86ms TTL=46

103.235.46.39 的 Ping 統計資料:
    封包: 已傳送 = 12,已收到 = 12, 已遺失 = 0 (0% 遺失),
大約的來回時間 (毫秒):
    最小值 = 76ms,最大值 = 101ms,平均 = 88ms
4年前 评论
joeyun (楼主) 4年前
joeyun (楼主) 4年前
Jason990420

d.execute_script (newwindow) 那表示还没 d.execute_script (newwindow), 就关闭连接了

问题不在 d.execute_script (newwindow)

这样问题不就缩小了, 目标就更明确 !

4年前 评论

是否有完整代码

4年前 评论
joeyun (楼主) 4年前
Jason990420
>>> urllib3.__version__
'1.25.8'
4年前 评论
joeyun (楼主) 4年前
joeyun (楼主) 4年前
Jason990420

再加上我的运行环境

  1. Python 3.7.6
  2. Selemiun 3.141.0
    别用未完成版的Seleniium, 本来那就是可能还有问题的版本, 或者说是测试版, 出问题是很正常的.
4年前 评论
joeyun (楼主) 4年前
Jason990420

按你的demo, 找一下问题

Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from selenium import webdriver
>>> driver = webdriver.Ie()
>>> print(driver.window_handles)
['ab749431-887e-4257-a6dd-344715ccc47d']
>>> print('Window Title', driver.title)
Window Title WebDriver

找到 webdriver 开的视窗标题为 WebDriver,
而且 window_handles = ['ab749431-887e-4257-a6dd-344715ccc47d']
注意该 handle 为 'ab749.....'

>>> driver.get('http://www.baidu.com')
>>> print(driver.window_handles)
['ab749431-887e-4257-a6dd-344715ccc47d']
>>> print('Window Title', driver.title)
Window Title 百度一下,你就知道

新开的视窗标题为 '百度一下,你就知道', 表示百度视窗已经打开了
注意该 handle 还是 'ab749.....', 表示是與 WebDriver 同一视窗

>>> newwindow = 'window.open("https://www.google.com")'
>>> driver.execute_script(newwindow)
>>> print(driver.window_handles)
['a4f878df-a053-47a1-8711-4206a0fc0a5a', 'ab749431-887e-4257-a6dd-344715ccc47d']
>>> print('Window Title', driver.title)
Window Title 百度一下,你就知道

在通过 JS 脚本的方式打开新窗口
此时视窗标题还是 '百度一下,你就知道', 代表雖然打幵了新视窗 Google, 但 WebDriver 还是指向百度视窗
另外新的 handle 加了进来, 是加在index为0, 不是index为1
所以如果要切换到 google 视窗, 要 driver.switch_to.window(driver.window_handles[0])
而不是driver.window_handles[1]

>>> driver.switch_to.window(driver.window_handles[0])
>>> print(driver.window_handles)
['a4f878df-a053-47a1-8711-4206a0fc0a5a', 'ab749431-887e-4257-a6dd-344715ccc47d']
>>> print('Window Title', driver.title)
Window Title Google

现在标题为 'Google' 了, 表示视窗已经切换过来了

>>> driver.close()
>>> print(driver.window_handles)
['ab749431-887e-4257-a6dd-344715ccc47d']
>>> print('Window Title', driver.title)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:\Software\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 342, in title
    resp = self.execute(Command.GET_TITLE)
  File "D:\Software\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "D:\Software\Python37\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchWindowException: Message: Unable to get browser

视窗关闭, 所以 handles 中只剩百度, driver 所指向的视窗也不存在, 所以读取视窗标题会出错

>>> driver.switch_to.window(driver.window_handles[0])
>>> print(driver.window_handles)
['ab749431-887e-4257-a6dd-344715ccc47d']
>>> print('Window Title', driver.title)
Window Title 百度一下,你就知道

既然, google 视窗已关闭, handles 就只剩百度, 当然得用 driver.window_handles[0]

>>> driver.close()
>>> print(driver.window_handles)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:\Software\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 724, in window_handles
    return self.execute(Command.W3C_GET_WINDOW_HANDLES)['value']
  File "D:\Software\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "D:\Software\Python37\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidSessionIdException: Message: session 31f6878d-e6eb-4324-ae4c-61f68a9bff98 does not exist

>>> print('Window Title', driver.title)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:\Software\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 342, in title
    resp = self.execute(Command.GET_TITLE)
  File "D:\Software\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "D:\Software\Python37\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidSessionIdException: Message: session 31f6878d-e6eb-4324-ae4c-61f68a9bff98 does not exist

百度视窗也关闭了, 所以handles, title都会出错

driver.quit()

不用 driver 了, 最后再把 driver 也关闭 !

4年前 评论
joeyun (楼主) 4年前
joeyun (楼主) 4年前
Jason990420

你的 demo 测试, 我跑起来结果是 OK !
网上有些说法, 不知道行不行....

IE的驱动不是IE作的, 所以常常会有问题, 还是不要用IE.

驱动的版本, 与BROWSER的版本经常是有闗系的

在请求/响应中发生意外情况时引发。

原因是urllib3的版本问题
pip install git+https://github.com/shazow/urllib3

4年前 评论
joeyun (楼主) 4年前
joeyun (楼主) 4年前
joeyun (楼主) 4年前
Jason990420

不是你的标题太短, 是你有用的内容太少, 把问题复杂化了, 看懂都不容易, 还能回吗 ?

  1. 确认您已完成以下步骤:
  • 您有一步一步找过问题吗?
  • 阅读有关如何提出问题的说明
  • 通过各网站搜索您的问题
  1. 问题/详细信息的描述 一个简短的程序,也许只有10行, 可以隔离并演示问题. 要缩小问题范围很痛苦,但这是调试过程的一部分。
4年前 评论
sw.run_script('window.open("https://www.baidu.com");')

试试

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!