Scrapy爬取动态内容(二)Selenium Chrome方案

Selemium参考文章:
https://www.jianshu.com/p/a1a64f649472
https://blog.csdn.net/htsait4113/article/details/84326817
 
https://blog.csdn.net/zhusongziye/article/details/80342781
https://www.cnblogs.com/gunduzi/p/10456327.html
https://juejin.im/entry/5adea7aff265da0b7451cc66
 
https://blog.csdn.net/fuck487/article/details/80852580
https://blog.csdn.net/lilongsy/article/details/80531378
https://www.jianshu.com/p/b35ebb1c1b0e
 
比较好的综合对比各种方案的文章
Python 分布式动态页面爬虫研究
https://juejin.im/entry/58de0c83a0bb9f0069dbcccf
 
Python 分布式动态页面爬虫研究
https://juejin.im/entry/58de0c83a0bb9f0069dbcccf
分布式Scrapy+chromedriver或Selenium Grid是实现分布式动态爬虫较好的选择。
 
chromedriver资源地址
http://npm.taobao.org/mirrors/chromedriver/
 
以当当图书详情页为例,多次对比了Splash和Selenium chome的采集效率:
Splash的平均采集时间为40s,并且时不时会失败
Selenium chrome的平均采集时间为10s,很少碰到失败。
说明chrome的效率和稳定性还是挺有保证的。
 

一、开发环境

安装selenium
pip install selenium
pip install isbnlib
 
根据平台选择安装chromedriver并移动至系统目录下,如/usr/local/bin
运行”chromedriver"检测是否安装成功。

二、使用

这里碰到了一个棘手的问题,就是在driver.get的时候,经常等待两分钟以上才会进入下一步,通过几天的摸索和搜索,发现可以通过配置加载策略解决这个问题。

1. PageLoadStrategy

参考文章:
https://www.jianshu.com/p/749974311f10
https://blog.csdn.net/wkb342814892/article/details/81611737
 
当调用driver.get("https://xxxx.xxx.xxx")来访问某页面时,get方法通常会阻塞浏览器直到页面完全加载后才执行后面的动作,若一个页面加载过慢,则会导致get方法一直阻塞。有时候希望页面在加载过程中就开始检测元素是否存在,而不是等到页面加载完了才开始检测,想要实现这个效果,可以用ChromeOptions类下的setPageLoadStrategy方法:
 
desired_capabilities = DesiredCapabilities.CHROME
desired_capabilities["pageLoadStrategy"] = "none"
driver = webdriver.Chrome(desired_capabilities=desired_capabilities,chrome_options=chrome_options)
 
其中PageLoadStrategy有三种选择:
(1) none: 当html下载完成之后,不等待解析完成,selenium会直接返回
(2) eager: 要等待整个dom树加载完成,即DOMContentLoaded这个事件完成,仅对html的内容进行下载解析
(3) normal: 即正常情况下,selenium会等待整个界面加载完成(指对html和子资源的下载与解析,如JS文件,图片等,不包括ajax)
 
实际上,对于一个新加载的dom,页面啥时候开始接受命令由页面的加载策略决定,也就是说,我们通过修改页面加载策略,可以使页面即使处于加载中,也能接受我们的命令,从这点可以解决webdriver.get的阻塞问题。而每类webdriver都有一个对应的配置文件放在特定的类DesiredCapabilities里面,通过修改里面的pageLoadStrategy,可以使webdriver的页面加载策略发生改变。

2、chrome参数设置

chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument("--disable-extensions")
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--no-sandbox")  # 取消沙盒模式, for linux root
chrome_options.add_argument("--headless")  # 浏览器不提供可视化页面
 
chrome_options.add_argument('--start-maximized')  # 最大化运行(全屏窗口),不设置,取元素会报错
chrome_options.add_argument('--disable-infobars')  # 禁用浏览器正在被自动化程序控制的提示
chrome_options.add_argument('--incognito')  # 隐身模式(无痕模式)
chrome_options.add_argument('blink-settings=imagesEnabled=false')  # 不加载图片
 
chrome_options.add_argument('log-level=2’)  # 日志级别
# info(default) = 0
# warning = 1
# LOG_ERROR = 2
# LOG_FATAL = 3

3、代理设置

这里发现动态变更代理是个挺麻烦的事情,目前根据下面的文章已经摸索成功并投入运行。
http://longofo.cc/selenium%E5%AE%9E%E7%8E%B0%E5%8A%A8%E6%80%81%E5%88%87%E6%8D%A2ip.html
 
麻烦的一点是打开的chrome实例需要定期清理,否则CPU使用率一直下不来,导致系统压力过大。

4、scrapy-async-selenium

Selenium在scrapy的异步使用,解决了已知阻塞的效率问题,又一篇神作,给了很大的启发!
整体方案是非常合理有效的。
 
已经在系统中成功使用,期间还有一些细节问题待进一步梳理。
 
 
 


posted on 2020-03-31 16:10  麦克煎蛋  阅读(852)  评论(0编辑  收藏  举报