内容简介:Python Webdriver 重新使用已经打开的浏览器实例
因为Webdriver每次实例化都会新开一个全新的浏览器会话,在有些情况下需要复用之前打开未关闭的会话。比如爬虫,希望结束脚本时,让浏览器处于空闲状态。当脚本重新运行时,它将继续使用这个会话工作。还就是在做自动化测试时,前面做了一大推操作,但是由于程序出错,重启时不用再继续前面复杂的操作。
个人觉得这种功能非常有用,但是官方居然没有提供这种功能的API,苦苦搜搜,在网上找了两个 java 版的http://blog.csdn.net/wwwqjpcom/article/details/51232302 和 http://woxiangbo.iteye.com/blog/2372683
看了下源码其实java和 python 的驱动原理过程都非常相似。
打开一个Chrome会话:
from selenium import webdriver driver = webdriver.Chrome()
运行上面的脚本,它将启动浏览器并退出。因为没有调用 quit()
方法,所以浏览器会话仍会存在。但是代码里创建的 driver
对象已经不在了,理论上不能用脚本控制这个浏览器。它将变成一个僵尸浏览器,只能手动杀死它。
通过webdriver启动一个浏览器会话大概会有这样三个阶段:
- 1、启动的浏览器驱动代理(hromedriver,Firefox的驱动程序,等等);
- 2、创建一个命令执行器。用来向代理发送操作命令;
-
3、使用代理建立一个新的浏览器会话,该代理将与浏览器进行通信。用
sessionId
来标识会话。
因此只要拿到阶段2中的执行器和阶段3中的 sessionID
就能恢复上次的会话。这两个有api可以直接获取:
from selenium import webdriver driver = webdriver.Chrome() executor_url = driver.command_executor._url session_id = driver.session_id print(session_id) print(executor_url) driver.get("http://www.spiderpy.cn/")
得到类似这样的输出(第一个是会话的sessionId,第二个就是命令执行器连接):
397d725f042a076f7d4a82f7d3fead13 http://127.0.0.1:52869
一切就绪,下面就开始实现复用之前会话的功能,在 Stack Overflow 上面讲的实现是这样的:
from selenium import webdriver driver = webdriver.Chrome() executor_url = driver.command_executor._url session_id = driver.session_id driver.get("http://www.spiderpy.cn/") print(session_id) print(executor_url) driver2 = webdriver.Remote(command_executor=executor_url, desired_capabilities={}) driver2.session_id = session_id print(driver2.current_url)
可能是因为版本原因吧,反正在我环境中运行时,效果是实现了,能够重新连接到上一个会话,但是却打开了一个新的空白会话。看了下 Remote
类的源码,发现是因为每次实例化都会调用 start_session
这个方法新建一个会话。所以解决方法就是继承并重写这个类。自定义一个 ReuseChrome
这个类重写 start_session
方法使它不再新建session,使用传入的session_id:
class ReuseChrome(Remote): def __init__(self, command_executor, session_id): self.r_session_id = session_id Remote.__init__(self, command_executor=command_executor, desired_capabilities={}) def start_session(self, capabilities, browser_profile=None): """ 重写start_session方法 """ if not isinstance(capabilities, dict): raise InvalidArgumentException("Capabilities must be a dictionary") if browser_profile: if "moz:firefoxOptions" in capabilities: capabilities["moz:firefoxOptions"]["profile"] = browser_profile.encoded else: capabilities.update({'firefox_profile': browser_profile.encoded}) self.capabilities = options.Options().to_capabilities() self.session_id = self.r_session_id
然后在第二次连接是使用重写的 ReuseChrome
类:
from selenium import webdriver # 第一次使用Chrome() 新建浏览器会话 driver = webdriver.Chrome() # 记录 executor_url 和 session_id 以便复用session executor_url = driver.command_executor._url session_id = driver.session_id # 访问百度 driver.get("http://www.spiderpy.cn/") print(session_id) print(executor_url) # 假如driver对象不存在,但浏览器未关闭 del driver # 使用ReuseChrome()复用上次的session driver2 = ReuseChrome(command_executor=executor_url, session_id=session_id) # 打印current_url为百度的地址,说明复用成功 print(driver2.current_url) driver2.get("https://www.baidu.com")
这样就能顺利连接到上次没关闭的浏览器会话。
文章地址: http://www.spiderpy.cn/blog/detail/36
以上所述就是小编给大家介绍的《Python Webdriver 重新使用已经打开的浏览器实例》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- vue之浏览器存储方法封装实例
- node 实例推导浏览器的渲染机制
- 恶意网站可利用浏览器扩展 API,窃取浏览器数据
- 360 浏览器:中国为什么没有自主研发的浏览器内核?
- 新版 Edge 浏览器或将拥有两个不同的浏览器内核
- [浏览器安全漏洞二] hao123桔子浏览器 – 页面欺骗漏洞
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Spring in Action
Craig Walls / Manning Publications / 2011-6-29 / USD 49.99
Spring in Action, Third Edition has been completely revised to reflect the latest features, tools, practices Spring offers to java developers. It begins by introducing the core concepts of Spring and......一起来看看 《Spring in Action》 这本书的介绍吧!
JS 压缩/解压工具
在线压缩/解压 JS 代码
URL 编码/解码
URL 编码/解码