https://github.com/Lee991211/Innovation_training.git
上一部分讲到了项目的spider部分,今天我们来看一下中间件以及管道部分。
下载器中间件是介入到Scrapy的spider处理机制的钩子框架,您可以添加代码来处理发送给 Spiders 的response及spider产生的item和request。
对于中间件更详细的编辑介绍,请关注scrapy官方文档的更新
https://scrapy-chs.readthedocs.io/zh_CN/latest/topics/spider-middleware.html
编写spider中间件十分简单。每个中间件组件是一个定义了以下一个或多个方法的Python类:
from_crawler() 用于根据传入的参数和 crawler 对象来生成 scheduler,使得 scheduler有crawler的属性和配置。
def from_crawler(cls, crawler): # This method is used by Scrapy to create your spiders. s = cls() crawler.signals.connect(s.spider_opened, signal=signals.spider_opened) return sprocess_spider_input 当response通过spider中间件时,该方法被调用,处理该response。
process_spider_output 当Spider处理response返回result时,该方法被调用。
process_spider_exception 当spider或(其他spider中间件的)process_spider_input() 跑出异常时, 该方法被调用。
process_start_requests 0.15 新版功能. 该方法以spider 启动的request为参数被调用,执行的过程类似于 process_spider_output() ,只不过其没有相关联的response并且必须返回request(不是item)。其接受一个可迭代的对象(start_requests 参数)且必须返回另一个包含 Request 对象的可迭代对象。
spider_opened 这我觉得不用说了。。。
与spider middlewares处理spider的输入(response)和输出(items及requests)不同,downloader middlewares处理Downloader传递给引擎的response。 内容基本同上,略
当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理。 每个item pipeline组件(有时称之为“Item Pipeline”)是实现了简单方法的Python类。他们接收到Item并通过它执行一些行为,同时也决定此Item是否继续通过pipeline,或是被丢弃而不再进行处理。 以下是item pipeline的一些典型应用: 清理HTML数据 验证爬取的数据(检查item包含某些字段) 查重(并丢弃) 将爬取结果保存到数据库中(或其他类型的文件中)
编写你自己的item pipeline很简单,每个item pipeline组件是一个独立的Python类,同时必须实现以下方法:
process_item(self, item, spider) 每个item pipeline组件都需要调用该方法,这个方法必须返回一个 Item (或任何继承类)对象, 或是抛出 DropItem 异常,被丢弃的item将不会被之后的pipeline组件所处理。
此外,他们也可以实现以下方法:
open_spider(self, spider) 当spider被开启时,这个方法被调用。
close_spider(spider) 当spider被关闭时,这个方法被调用
weibo项目的pipeline有csv、mongodb、mysql、pic、vid
根据目录、文件是否存在而进行文件及文件夹的创建、写入。csv文件里的列有:‘id’, ‘bid’, ‘user_id’, ‘用户昵称’, ‘微博正文’, ‘头条文章url’,‘发布位置’, ‘艾特用户’, ‘话题’, ‘转发数’, ‘评论数’, ‘点赞数’, ‘发布时间’,‘发布工具’, ‘微博图片url’, ‘微博视频url’, ‘retweet_id’
def process_item(self, item, spider): base_dir = '结果文件' + os.sep + item['keyword'] if not os.path.isdir(base_dir): os.makedirs(base_dir) file_path = base_dir + os.sep + item['keyword'] + '.csv' if not os.path.isfile(file_path): is_first_write = 1 else: is_first_write = 0 if item: with open(file_path, 'a', encoding='utf-8-sig', newline='') as f: writer = csv.writer(f) if is_first_write: header = [ 'id', 'bid', 'user_id', '用户昵称', '微博正文', '头条文章url', '发布位置', '艾特用户', '话题', '转发数', '评论数', '点赞数', '发布时间', '发布工具', '微博图片url', '微博视频url', 'retweet_id' ] writer.writerow(header) writer.writerow( [item['weibo'][key] for key in item['weibo'].keys()]) return item至此微博爬虫项目结束,代码实现比较困难的地方在search的parse()函数,刚了解scrapy的时候,样例项目的spider类只有一个parse()函数,后来在操作的时候发现应当类似递归的定义parse,用以天为单位调用以小时为单位。。。。。。 同时另一个比较大的困难就是,虽然scrapy是一个很成熟的框架,然而对有些方法不熟悉使得要一次次查看文档,而且一些神奇的报错(后来证实多为网络、cookies错误)完全摸不着头脑。