基本功能:
执行脚本 a, 打开一个 Chrome, 脚本 a 执行完成, Chrome 未关闭.
执行脚本 b, 继续使用 a 打开的 Chrome, 不新启浏览器.
附加:
如果已打开的 Chrome 未关闭, 则在 Chrome 中新建标签页来打开新的页面.
如果已打开的 Chrome 已关闭, 则新启浏览器.
最近用 python+selenium+pytest, 写了个测试小工具用来自动化登陆浏览器, 一方面是方便管理网址, 账号, 密码, 存放在脚本中, 另一方面也省去了频繁输入登陆网站的操作, 节省了不少时间.
但这个小工具用起来存在明显问题: 每次都新启一个浏览器, 多了后就是这样的
根本不知道谁是谁.
于是就想到要实现前面提到的这些功能.
首先要解决的第一个问题就是, 怎么重新使用已打开的 Chrome. 百度后知晓, 是通过 session_id. 浏览器都有一个 session_id, 拿到这个 session_id 就可以通过 webdriver.Remote 去调 Chrome.
- driver = webdriver.Chrome()
- params["session_id"] = driver.session_id
- params["server_url"] = driver.command_executor._url
- driver = webdriver.Remote(command_executor=params["server_url"])
- driver.session_id = params["session_id"]
经过试验, python 存在一个坑是每次初始化就会调 start_session 去新开一个空白的浏览器. 网上有解决方案是继承 Remote, 重写 start_session 方法. 然而, 仔细看完代码就发现, 何必多此一举, 直接 quit() 就搞定.
- driver = webdriver.Remote(command_executor=params["server_url"])
- driver.quit() # 退出 start_session 新开的空白浏览器
- driver.session_id = params["session_id"]
quit 是 quit 了, 但 driver 还存在呀, 所以还是多理清思路, 才能避免走冤枉路.
然后要解决的第二个问题就是, 如何在执行脚本 b 的时候再接着用 session. 当然就是存本地咯. 这里用到的是 pickle, 能很方便的在本地存取变量.
存
- with open(session_file, 'wb') as f:
- pickle.dump(params, f)
取
- with open(session_file, 'rb') as f:
- params = pickle.load(f)
第三个问题就是新开标签页和切换窗口.
- driver.execute_script('window.open("");') # 调 JS
- driver.switch_to.Windows(driver.window_handles[-1]) # 切换到最后一个页签
最后要解决的一个问题就是, 如果已经打开的 Chrome 关掉了, 从本地文件读取的 session 就会过时. 拿这个过时 session 去用, 就会 "chrome not reachable". 解决思路就是, 捕获 driver 抛出的 WebDriverException, 重新创建新的 driver.
- try:
- driver = webdriver.Remote(command_executor=params["server_url"])
- driver.quit() # 退出 start_session 新开的空白浏览器
- driver.session_id = params["session_id"]
- driver.execute_script('window.open("");')
- driver.switch_to.Windows(driver.window_handles[-1])
- except:
- driver = create_driver()
完整代码
- session_file = 'browser_session.data'
- def create_driver():
- driver = webdriver.Chrome()
- with open(session_file, 'wb') as f:
- params = {"session_id": driver.session_id, "server_url": driver.command_executor._url}
- pickle.dump(params, f)
- return driver
- if not Path(session_file).exists():
- driver = create_driver()
- else:
- with open(session_file, 'rb') as f:
- params = pickle.load(f)
- try:
- driver = webdriver.Remote(command_executor=params["server_url"])
- driver.quit() # 退出 start_session 新开的空白浏览器
- driver.session_id = params["session_id"]
- driver.execute_script('window.open("");')
- driver.switch_to.Windows(driver.window_handles[-1])
- except:
- driver = create_driver()
版权申明: 本文为博主原创文章, 转载请保留原文链接及作者.
来源: http://www.bubuko.com/infodetail-3257885.html