Scrapy爬取动态内容(二)Selenium Chrome方案
Selemium参考文章:
比较好的综合对比各种方案的文章
Python 分布式动态页面爬虫研究
Python 分布式动态页面爬虫研究
分布式Scrapy+chromedriver或Selenium Grid是实现分布式动态爬虫较好的选择。
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
参考文章:
当调用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、代理设置
这里发现动态变更代理是个挺麻烦的事情,目前根据下面的文章已经摸索成功并投入运行。
麻烦的一点是打开的chrome实例需要定期清理,否则CPU使用率一直下不来,导致系统压力过大。
4、scrapy-async-selenium
Selenium在scrapy的异步使用,解决了已知阻塞的效率问题,又一篇神作,给了很大的启发!
整体方案是非常合理有效的。
已经在系统中成功使用,期间还有一些细节问题待进一步梳理。