一直在服务器上运行selenium + chromedriver 方式做爬虫, 发现服务器的负载居高不下, 优化了几次supervisor的进程数, 也没有好转......
最近还发现chrome进程又残余....服务器不卡才怪咧....
一怒之下查看了selenium的源码, 找解决办法....
我使用的是seleniumwire, 这个第三方包是基于selenium二次封装, 增加了许多实用的功能,
1) 简单地为chrome浏览器配置代理 (简直是爬虫党的福音, 不过你不嫌麻烦可以在脚本中每次都安装代理插件....)
2) 捕捉所有的请求, 有点像中间人攻击的味道, 用途挺多, 可以改header, 过滤request, 吧啦吧啦......
那么, 我们就首先看看seleniumwire的源码吧....看他究竟做了些什么鬼
先看初始化方法__init__, 先是调用了一个create_proxy的方法, 哦, 可能有的小伙伴会问这事什么意思, 英语菜不能怪我啊~
就是创建代理, 步入方法里看看呗....
原理是在本地创建了一个代理服务, 把所有请求都转发到我们作为初始化方法参数传进去的代理, 简单说就是二级代理,
来到这里, 差不多就可以知道代码作者的意图了, 就是通过在本地搭建一个http代理服务,来实现真正代理的转发和中间人的作用
回到初始化方法, 最后调用了父类的初始化方法
那么他的父类是谁呢?
一番追溯, 果然还是selenium中的chrome driver 类, 兜兜转转还是回来了....
那我们也看一下他的初始化方法吧
果然发现有坑!!!!!!!!!!!!!!!!!
前边的逻辑就是加载各种chrome的配置, 后边每实例化一个chrome webdriver实例, 都会开启一个与之对应的driver服务....
来到这里, 我又想起一句最近很火的歌词, 小朋友, 你是否有很多问号?????
这里我安利另一篇我个人觉得写得不错的文章 https://www.jianshu.com/p/195ff63921de
这个webdriber服务, 就是将我们在python脚本中调用的selenium方法, 转化为对chrome浏览器的操作
下面举个例子, 例如我们在脚本调用了 driver.get(url), 使用浏览器访问一个url网址
调用了execute方法执行了与之对应的command
进入execute方法看下:
延伸一下session_id, 效果就是打开了一个浏览器, 是在webdirver类的初始化方法创建的....没留意到的人请自觉点赞......
言归正传, 继续深入, 看command_executor的execute方法,
RemoteConnection这个类才是归根到底, 是如何去发http请求driver服务,最终转化为操作浏览器命令的所在
看下边的命令, 是不是有点头绪了呢...
至此我也是刚发现, 原来调用selenium中的很多方法都是有返回值的, 就是driver服务的响应内容
跑题了!!! 回到最初....说了辣么多, 大概都懂了吧
优化方向就有了, 原先是每个实例开启一个driver服务, 改进为多个实例共用一个driver服务,
是否可行??? 官方文档都建议共用一个driver服务
看了官方文档案例用的是Remote的链接方式,其好处是每次启动chromedriver,都是通过remote的方式去连接到共用的chromedriver(开放9515端
口),这样子能够节省很多服务器的资源;而直接用webserver.Chrome的方式连接chromedriver
开始改造: 为了不影响源码, 我把selenium chrome webdriver 的类复制一份, 单独拿来修改,
改完啦, 看懂一两天, 改造一分钟, 这就完事了, 真短~~~~(我说的是时间)
ok 在本地开启9515的driver服务 , 试下运行测试脚本, 脚本中记得要引入的是我们自己改造的类, 不是selenium的原始类
有这句输出证明我们使用改造好的类, 再用ps查看 chromedirver相关进程, 一直只有一个9515端口的进程,
改造成功!!!!!!!!!!!!!!!!!!!!!!撒花
有个东西注意一下, quit方法在退出的时候要把self.seriver的相关操作注释掉, 否则会报错
ps -ef|grep chrome|wc -l 查看一下chrome的进程, 比之前少了很多很多, 嗨心~~~~~
最后埋个坑给大家:
造成chrome残余进程的一个原因, 在driver实例化的时候失败, 最后不能调用quit方法退出
有能解决的大佬评论一下
百度一下查到了可能的原因,
可能是代理商服务器压力太大, 主动关闭了一些tcp链接.....这可坑了我~~~~
好了, 写得不怎么样, 有问题有建议可以评论留言....
赛有拉拉