python爬虫–Scrapy框架–Scrapy+selenium实现动态爬取
前言
本文基于数据分析竞赛爬虫阶段,对使用scrapy + selenium进行新闻文本爬虫进行记录。
框架结构
start启动scrapy -> 爬虫提交链接request(可以有多条链接)给Scheduler -> Scheduler决定链接的调度(调度器应该是个优先队列,起到分配线程的作用,用分布式爬虫来加快爬取速度)-> Scheduler把请求的链接发送给下载器(下载器可以配置middlewares) -> 下载器发送request给网页服务器 -> 网络服务器将response对象返回给下载器 -> 下载器将response下载发送给爬虫 -> 爬虫解析response返回的对象并进行后续操作(给Item Pipeline发送存储请求or再次发起链接请求)
创建爬虫
cd <项目文件夹>
scrapy startproject SpiderProjectName
... ...
cd SpiderProjectName
# 创建普通爬虫
scrapy genspider spider_name xxx.com
# 创建crawlspider(可定义抓取规则,自动抓取链接)
scrapy genspider -t crawl spider_name xxx.com
配置settings
- 不遵循爬虫协议(建议改成False)
ROBOTSTXT_OBEY = False
当要用到下面的构件时,在settings.py中找到下面代码,去掉#号即可
- 开启下载器中间件
DOWNLOADER_MIDDLEWARES = {
'testSpider.middlewares.TestspiderDownloaderMiddleware': 543,
}
-
设置header
-
开启pipelines
重写方法
- 在你的spider.py文件重写start_requests(self)方法,可以传入自定义的链接请求(用函数的方式生成链接)
- 在middlewares中重写中间件方法,可以实现自己的功能(例如利用selenium进行模拟点击)
配合selenium实现动态爬取
- scrapy可以高效实现页面抓取,scrapy的crawlspider类可以自动抓取链接并前往链接解析内容。
- selenium可以实现动态点击,能够获得加载完整的page_source,与scrapy互补
selenium的安置方法
爬虫将url传入到middlewares,因此应在middlewares的process_request()方法中向服务器发送操作请求,再用driver.page_source解析网页源码,此时服务器response的源码加载了动态生成的内容
- 爬虫每发送一次url请求,process_request()调用一次。如果要加载动态内容,那么selenium只能安放在这里
crawlspider
crawlspider只能抓取response返回的源码中符合Rule的链接,再访问链接里的内容。
- 对于满足rules的链接,crawlspider会再次将这些链接向middlewares发送request,因此middlewares中的process_request, process_response方法也会再次调用
- Rule()里定义LinkExtractor规则,LinkExtractor()方法参数常用的有:allow:只有正则匹配成功的链接才捕获;restrict_xpath:规定xpath格式的链接才捕获
问题
如何才能在start_url中动态点击按钮获得下一个链接的同时,解析数据返回给爬虫,同时selenium能够在当前页面继续爬取(比如要爬取新闻文本,点击下一页按钮(按钮是js加载,因此没有链接),生成了新的页面,抓取新页面的新闻链接后,再在该页面基础上点击下一页面获得新页面源码)?
补充:process_request不能采用yield方法,因为yield方法返回的是一个包装了链接的生成器(generator)对象,而不是普通的链接,scrapy是处理不了这种对象的
解决方案
思路:将爬虫分成两步:
一、先爬取所有项目对应的所有链接,并存储到数据库中。数据库设计如下
post_url | category |
---|
二、在start_requests方法中,按page yield成新界面的url对爬虫发送请求。对于发送的页面链接,在process_request用selenium进行get()方法处理,并return HtmlResponse(url, body = self.driver.page_source, request = request, encoding = 'utf-8')
。此时返回的页面是动态加载生成的页面,用crawlspider自动捕获新闻链接,并重新向爬虫发送请求,获得的新闻链接在parse方法中进行处理。
此时爬虫的工作就已经完成,后续只需将parse中将新闻链接中要提取的数据打包成item,并且一定要保留他的post_url,将打包好的item返回给pipeline,保存到数据库中。将一和二的数据库按照post_url进行连接,就可以得到所需要的文本信息了。此时爬虫工作成功完成。