一日一技:使用上下文管理器来强制关闭 Chromedriver

简介: 一日一技:使用上下文管理器来强制关闭 Chromedriver

摄影:产品经理与产品经理环游世界

当我们使用 Selenium 通过 Chromedriver 启动 Chrome 浏览网页时,可能会由于某些异常情况导致程序崩溃,但 Chromedriver 进程不会退出。

例如,我们编写一段显然有问题的代码:

from selenium.webdriver import Chrome
driver = Chrome('./chromedriver')
driver.get('https://www.kingname.info')
1 + 'a'# 这一行代码必定导致程序崩溃

代码报错以后,弹出的 Chrome 窗口不会自动关闭。并且 chromedriver 的进程也不会自动结束,如下图所示:

这就会导致系统中出现越来越多的 chromedriver 进程,从而占用大量的内存。

为了防止这种情况,我们必须想办法,在任何情况下都需要保证退出 chromedriver。

你可能会使用一个超大型的 try ... except...把所有与 selenium 相关的代码都包起来:

from selenium.webdriver import Chrome
driver = Chrome('./chromedriver')
try:
    driver.get('https://www.kingname.info')
 #第2行
 #第3行
 #第4行
 #。。。
 #第 n 行
except Exception:
    driver.quit()

当然你也可以把具体的操作步骤放在函数里面,然后 try...except... 把函数包住。但本质上是一样的。

但这种超大型的 try...except...一是会导致程序速度减慢,二是程序出现了其他异常的时候,真正的报错信息无法正常打印出来:

>>> a = {}
>>> try:
>>>    a['k']
>>> except Exception as e:
>>>    print(e)

当你看到这个没头没尾的'k',你不知道是哪一行有问题,也不知道具体有什么问题。

那么,我们有没有办法,既不使用 try ... except ...,但是又能在程序崩溃的时候自动退出 chromedriver 呢?

这个时候我们就可以使用上下文管理器。

我们先来包装一下 Selenium,实现一个带有上下文管理器的类。创建一个SafeDriver.py文件:

from selenium.webdriver import Chrome
class SafeDriver:
    def __init__(self):
        self.driver = Chrome('./chromedriver')
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.driver:
            self.driver.quit()

然后,我们在另一个程序里面调用它:

from SafeDriver import SafeDriver
safe_driver = SafeDriver()
with safe_driver as driver:
    driver.driver.get('https://www.kingname.info')
    a = {}
    a['k']

程序进入到with safe_driver as driver的缩进里面,我们会得到一个driver变量,它可以用来操作浏览器。

我们只需要在缩进里面正常写代码即可。一旦由于某种原因导致缩进里面的代码报错,Python 自动会进入SafeDriver类的__exit__方法中,执行里面的代码。在这个方法里面,我们就可以关闭 chromedriver。从而保证只要程序异常退出,浏览器一定会被关闭,不会遗留进程。

运行效果如下图所示:

报错信息和出错的行数都能正常打印出来了。

我们来看看如何实现一个包含上下文管理器的程序:

  1. 随意定义一个类,里面写好你需要执行的逻辑
  2. 增加__enter__(self)方法,定义进入上下文管理器时返回的内容
  3. 增加__exit__(self, exc_type, exc_val, exc_tb)方法,定义退出上下文管理器时需要执行的代码

需要注意的是,__enter____exit__需要成对使用,不能单独使用其中一个。

在上面的代码中,__enter__方法仅仅返回了self,于是,下面两段代码:

safe_driver = SafeDriver()
with safe_driver as instance:
    pass

仅仅从功能上来说,instance 变量与safe_driver变量完全一样,都可以使用safe_driver.driverinstance.driver

所不同的是,使用with启用上下文管理器以后,在退出缩进的时候会执行__exit__中的内容。

为了简便起见,我们可以使用with safe_driver.driver as driver,直接拿到对象中的self.driver属性,这样可以直接使用类似于driver.get('https://www.kingname.info')访问网站,而不是instance.driver.get('https://www.kingname.info')。少敲几次键盘。

目录
相关文章
|
3月前
|
Web App开发 缓存 安全
Chrome浏览器启动参数大全
这是一组用于定制浏览器行为的命令行参数,包括但不限于:不停用过期插件、放行非安全内容、允许应用中心脚本、停用GPU加速视频、禁用桌面通知、禁用拓展及各类API、调整缓存设置、启用打印预览、隐身模式启动、设定语言、使用代理服务器、无头模式运行等。通过这些参数,用户可以根据需求灵活调整浏览器功能与性能。
|
Linux PHP Windows
|
IDE 编译器 开发工具
问题:窗体在运行时显示,在解决方案管理器中不显示
小引: 虽然我知道实现《机房收费管理系统》会遇见各种问题,但是碰到这么狗血的问题,我真是大姑娘上花轿——头一回!
106 0
|
Shell C#
C#使用Process打开外部程序或外部文件的使用总结
执行一个外部的第三方应用的原理,和调用cmd执行命令是一样的,只不过可以添加程序的启动参数(`StartInfo.Arguments`)等。调用第三方应用,在其启动后,关于程序的操作、处理、是否...
1912 0
C#使用Process打开外部程序或外部文件的使用总结
|
C# Windows
Win32 程序在启动时激活前一个启动程序的窗口
原文:Win32 程序在启动时激活前一个启动程序的窗口 版权声明:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:http://blog.csdn.net/wpwalter/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
1072 0
|
开发框架 Java .NET
session在浏览器关闭时进行何处理?以及回收机制
当浏览器关闭的时候,会 清空Cookies ,这是浏览器对自己软件的操作,但是并不能对服务端的储存文件进行操作,所以这个时候服务端的session文件将继续生存。 当我们关闭浏览器,甚至电脑重启,短时间内服务端的session仍保存着,直到它被回收,这个时候我们通过一些手段模拟sessionid,仍可以继续保持会话进行。
206 0
|
关系型数据库 MySQL 数据库连接
上下文管理器 | 学习笔记
快速学习 上下文管理器
|
Web App开发 iOS开发
Chrome插件管理器
Chrome插件管理器
233 0
Chrome插件管理器
|
编解码 移动开发 Python
Beets:命令行上的音乐库管理器
Beets 是一个专为那些强迫性人格(obsessive-compulsive)又痴迷音乐的 geek 打造的媒体库管理系统。
326 0
Beets:命令行上的音乐库管理器
|
Web App开发 数据安全/隐私保护
chrome浏览器每次都打开独立窗口bat实现
chrome浏览器每次都打开独立窗口bat实现
1286 0

热门文章

最新文章