如何重用 selenium 浏览器会话
How to reuse a selenium browser session
我正在尝试从单独的 python 进程访问现有的 selenium 浏览器会话。我能够在同一个 python 脚本中实现它,但是当我将重用逻辑分解为一个单独的脚本时,它失败并显示错误消息:
Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 1318, in do_open
encode_chunked=req.has_header('Transfer-encoding'))
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1239, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1285, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1234, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1026, in _send_output
self.send(msg)
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 964, in send
self.connect()
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 936, in connect
(self.host,self.port), self.timeout, self.source_address)
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 722, in create_connection
raise err
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 713, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 61] Connection refused
这是尝试从单独的脚本访问现有会话的代码(这是生成错误的代码)。现在我每次都手动更新 session_id 和 executor 值:
""" module docstring """
import time
from selenium import webdriver
def main():
""" reuse window in different scripts """
# driver = webdriver.Chrome()
session_id = '7b10acc2c99d90a68fecb71e5e481c0f'
# executor_url = 'http://127.0.0.1:9515'
executor_url = 'http://127.0.0.1:54467'
print(session_id)
print(executor_url)
driver2 = webdriver.Remote(command_executor=executor_url,
desired_capabilities={})
print('driver instance created')
driver2.session_id = session_id
print(driver2.current_url)
driver2.get('http://www.yahoo.com')
time.sleep(10)
if __name__ == '__main__':
main()
这是设置初始浏览器会话的代码:
""" module docstring """
import time
from selenium import webdriver
def main():
""" reuse window in different scripts """
driver = webdriver.Chrome()
executor_url = driver.command_executor._url # pylint: disable=W0212
session_id = driver.session_id
driver.get("http://tarunlalwani.com")
print(session_id)
print(executor_url)
time.sleep(300)
if __name__ == '__main__':
main()
这是成功改变现有浏览器 window 的脚本,但它来自同一个 python 脚本:
""" module docstring """
import time
from selenium import webdriver
def main():
""" reuse window in same script """
driver = webdriver.Chrome()
executor_url = driver.command_executor._url # pylint: disable=W0212
session_id = driver.session_id
driver.get("http://tarunlalwani.com")
print(session_id)
print(executor_url)
driver2 = webdriver.Remote(command_executor=executor_url,
desired_capabilities={})
driver2.session_id = session_id
print(driver2.current_url)
driver2.get('http://www.yahoo.com')
time.sleep(300)
if __name__ == '__main__':
main()
这是一个使用单文件解决方案的示例,但它也适用于双文件解决方案。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from multiprocessing import Process
import time
# The main process calls this function to create the driver instance.
def createDriverInstance():
options = Options()
options.add_argument('--disable-infobars')
driver = webdriver.Chrome(chrome_options=options, port=9515)
return driver
# Called by the second process only.
def secondProcess(executor_url, session_id):
options = Options()
options.add_argument("--disable-infobars")
options.add_argument("--enable-file-cookies")
capabilities = options.to_capabilities()
same_driver = webdriver.Remote(command_executor=executor_url, desired_capabilities=capabilities)
same_driver.close()
same_driver.session_id = session_id
same_driver.get("https://www.wikipedia.org")
time.sleep(4)
same_driver.quit()
if __name__ == '__main__':
driver = createDriverInstance()
driver.get("https://google.com")
time.sleep(2)
# Pass the driver session and command_executor to the second process.
p = Process(target=secondProcess, args=(driver.command_executor._url,driver.session_id))
p.start()
如果你想要终极性能,你可以让Selenium作为一个HTTP
服务器来接收命令。示例:
# Created by BaiJiFeiLong@gmail.com at 2022/1/29 11:58
import threading
import flask
import requests
import selenium.webdriver
app = flask.Flask(__name__)
@app.post("/")
def home():
return str(driver.execute_script(flask.request.data.decode()))
threading.Thread(target=lambda: app.run(host="127.0.0.1", port=5000)).start()
driver = selenium.webdriver.Chrome()
print("1+1=", requests.post("http://localhost:5000", "return 1+1").text)
print("userAgent=", requests.post("http://localhost:5000", "return navigator.userAgent").text)
我正在尝试从单独的 python 进程访问现有的 selenium 浏览器会话。我能够在同一个 python 脚本中实现它,但是当我将重用逻辑分解为一个单独的脚本时,它失败并显示错误消息:
Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py", line 1318, in do_open
encode_chunked=req.has_header('Transfer-encoding'))
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1239, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1285, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1234, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 1026, in _send_output
self.send(msg)
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 964, in send
self.connect()
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/http/client.py", line 936, in connect
(self.host,self.port), self.timeout, self.source_address)
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 722, in create_connection
raise err
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/socket.py", line 713, in create_connection
sock.connect(sa)
ConnectionRefusedError: [Errno 61] Connection refused
这是尝试从单独的脚本访问现有会话的代码(这是生成错误的代码)。现在我每次都手动更新 session_id 和 executor 值:
""" module docstring """
import time
from selenium import webdriver
def main():
""" reuse window in different scripts """
# driver = webdriver.Chrome()
session_id = '7b10acc2c99d90a68fecb71e5e481c0f'
# executor_url = 'http://127.0.0.1:9515'
executor_url = 'http://127.0.0.1:54467'
print(session_id)
print(executor_url)
driver2 = webdriver.Remote(command_executor=executor_url,
desired_capabilities={})
print('driver instance created')
driver2.session_id = session_id
print(driver2.current_url)
driver2.get('http://www.yahoo.com')
time.sleep(10)
if __name__ == '__main__':
main()
这是设置初始浏览器会话的代码:
""" module docstring """
import time
from selenium import webdriver
def main():
""" reuse window in different scripts """
driver = webdriver.Chrome()
executor_url = driver.command_executor._url # pylint: disable=W0212
session_id = driver.session_id
driver.get("http://tarunlalwani.com")
print(session_id)
print(executor_url)
time.sleep(300)
if __name__ == '__main__':
main()
这是成功改变现有浏览器 window 的脚本,但它来自同一个 python 脚本:
""" module docstring """
import time
from selenium import webdriver
def main():
""" reuse window in same script """
driver = webdriver.Chrome()
executor_url = driver.command_executor._url # pylint: disable=W0212
session_id = driver.session_id
driver.get("http://tarunlalwani.com")
print(session_id)
print(executor_url)
driver2 = webdriver.Remote(command_executor=executor_url,
desired_capabilities={})
driver2.session_id = session_id
print(driver2.current_url)
driver2.get('http://www.yahoo.com')
time.sleep(300)
if __name__ == '__main__':
main()
这是一个使用单文件解决方案的示例,但它也适用于双文件解决方案。
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from multiprocessing import Process
import time
# The main process calls this function to create the driver instance.
def createDriverInstance():
options = Options()
options.add_argument('--disable-infobars')
driver = webdriver.Chrome(chrome_options=options, port=9515)
return driver
# Called by the second process only.
def secondProcess(executor_url, session_id):
options = Options()
options.add_argument("--disable-infobars")
options.add_argument("--enable-file-cookies")
capabilities = options.to_capabilities()
same_driver = webdriver.Remote(command_executor=executor_url, desired_capabilities=capabilities)
same_driver.close()
same_driver.session_id = session_id
same_driver.get("https://www.wikipedia.org")
time.sleep(4)
same_driver.quit()
if __name__ == '__main__':
driver = createDriverInstance()
driver.get("https://google.com")
time.sleep(2)
# Pass the driver session and command_executor to the second process.
p = Process(target=secondProcess, args=(driver.command_executor._url,driver.session_id))
p.start()
如果你想要终极性能,你可以让Selenium作为一个HTTP
服务器来接收命令。示例:
# Created by BaiJiFeiLong@gmail.com at 2022/1/29 11:58
import threading
import flask
import requests
import selenium.webdriver
app = flask.Flask(__name__)
@app.post("/")
def home():
return str(driver.execute_script(flask.request.data.decode()))
threading.Thread(target=lambda: app.run(host="127.0.0.1", port=5000)).start()
driver = selenium.webdriver.Chrome()
print("1+1=", requests.post("http://localhost:5000", "return 1+1").text)
print("userAgent=", requests.post("http://localhost:5000", "return navigator.userAgent").text)