当前位置: 首页 > 工具软件 > go_spider > 使用案例 >

python pipeline框架_爬虫(十六):Scrapy框架(三) Spider Middleware、Item Pipeline|python基础教程|python入门|python教程...

邬楚青
2023-12-01

https://www.xin3721.com/eschool/pythonxin3721/

1. Spider Middleware

Spider Middleware是介入到Scrapy的Spider处理机制的钩子框架。

当Downloader生成Response之后,Response会被发送给Spider,在发送给Spider之前,Response会首先经过Spider Middleware处理,当Spider处理生成Item和Request之后,Item Request还会经过Spider Middleware的处理。

Spider Middleware有三个作用:

我们可以在Downloader生成的Response发送给Spider之前,也就是在Response发送给Spider之前对Response进行处理。

我们可以在Spider生成的Request发送给Scheduler之前,也就是在Request发送给Scheduler之前对Request进行处理。

我们可以在Spider生成的Item发送给Item Pipeline之前,也就是在Item发送给Item Pipeline之前对Item进行处理。

1.1 使用说明

需要说明的是,Scrapy其实已经提供了许多Spider Middleware,它们被SPIDER_MIDDLEWARES_BASE这个变盘所定义。

SPIDER_MIDDLEWARES_BASE变量的内容如下:

{

'scrapy.spidermiddlewares.httperror.HttpErrorMiddleware':50,

'scrapy spidermiddlewares offsite Of site iddleware':500,

'scrapy.spidermiddlewares.referer.RefererMiddleware':700,

'scrapy.spidermiddlewares.urllength.UrllengthMiddleware':800,

'scrapy.spidermiddlewares.depth.DepthMiddleware':900,

}

和Downloader Middleware一样,Spider Middleware首先加入到SPIDER_MIDDLEWARES设置中,该设置会和Scrapy中SPIDER_MIDDLEWARES_BASE定义的Spider Middleware合并。然后根据键值的数字优先级排序,得到一个有序列表。第一Middleware是最靠近引擎的,最后一个Middleware是最靠近Spide的。

1.2 核心方法

Scrapy内置的Spider Middleware为Scrapy提供了基础的功能。如果我们想要扩展其功能,只需要实现某几个方法即可。

每个Spider Middleware都定义了以下一个或多个方法的类,核心方法有如下4个。

process_spider_input(response,spider)

process_spider_output(response,result,spider)

process_spider_exception(response,exception,spider)

proce ss_start_requests(start_requests,spider)

只需要实现其中一个方法就可以定义一个Spider Middleware。

(1) process_spider_input(response,spider)

当Response被Spider Middleware处理时,process_spider_input()方法被调用。

process_spider_input()方法的参数有如下两个:

response,是Response对象,即被处理的Response。

spider,是Spider对象,即该Response对应的Spider。

process_spider_input()应该返回None或者抛出一个异常。

如果它返回None,Scrapy将会继续处理该Response,调用所有其他的Spider Middleware,直到Spider处理该Response。

如果它抛出一个异常,Scrapy将不会调用任何其他Spider Middleware的process_spider_input()方法,而调用Request的errback()方法。errback的输出将会被重新输入到中间件中,使用process_spider_output()方法来处理,当其抛出异常时则调用process_spider_exception()来处理。

(2) process _spider_output(response,result,spider)

当Spider处理Response返回结果时,process_spider_output()方法被调用。process_spider_output()方法的参数有如下三个:

response,是Response对象,即生成该输出的Response。

result,包含Request或Item对象的可迭代对象,即Spider返回的结果。

spider,是Spider对象,即其结果对应的Spider。

process_spider_output()必须返回包含Request或Item对象的可迭代对象。

(3) process_spider_exception(response,exception,spider)

当Spider或Spider Middleware的process_spider_input()方法抛出异常时,process_spider_exception()方法被调用。

process_spider_exception()方法的参数有如下三个:

response,是Response对象,即异常被抛出时被处理的Response。

exception,是Exception对象,即被抛出的异常。

spider,是Spider对象,即抛出该异常的Spider。

process_spider_exception()必须要么返回None,要么返回一个包含Response或Item对象的可迭代对象。

如果它返问None,Scrapy将继续处理该异常,调用其他Spider Middleware中的process_spider_exception()方法,直到所有Spider Middleware都被调用。

如果它返回一个可迭代对象,Spider Middleware的process_spider_output()方法被调用,其他的process_spider_exception()不会被调用。

(4) process_start_requests (start_requests,spider)

process_start_requests()方法以Spider启动的Request为参数被调用,执行的过程类似于process_spider_output(),只不过它没有相关联的Response并且必须返回Request。

proces s_start_requests()方法的参数有如下两个:

start_requests,是包含Request的可迭代对象,即Start Requests。

spider,是Spider对象,即Start Requests所属的Spider。

process_start_requests()必须返回另一个包含Request对象的可迭代对象。

回到顶部(go to top)

2. Item Pipeline

Item Pipeline是项目管道。

Item Pipeline的调用发生在Spider产生Item之后。当Spider解析完Response之后,Item就会传递到Item Pipeline,被定义的Item Pipeline组件会依次调用,完成一连串的处理过程,比如数据清洗、存储等。

Item Pipeline主要功能有四点:

清理HTML数据。

验证爬取数据,检查爬取字段。

查重并丢弃重复内容。

将爬取结果保存到数据库。

我们可以自定义Item Pipeline,只需要实现指定的方法,其中必须要实现的一个方法是: process_item(item,spider)。

另外还有如下几个比较实用的方法:

open_spider(spider)

close_spider(spider)

from_crawler(cls,crawler)

2.1 常用方法

(1) process_item(item,spider)

process_item()是必须要实现的方法,被定义的Item Pipeline会默认调用这个方法对Item进行处理。比如,我们可以进行数据处理或者将数据写入到数据库等操作。它必须返回Item类型的值或者抛出一个DropItem异常。

process_itern()方法的参数有两个:

item,是Item对象,即被处理的Item。

Spider,是Spider对象,即生成该Item Spider。

process_item()方法的返回类型归纳如下:

如果它返回的是Item对象,那么此Item会被低优先级的Item Pipeline的process_item()方法处理,直到所有的方法被调用完毕。

如果它抛出的是DropItem异常,那么此Item会被丢弃,不再进行处理。

(2) open_spider(self,spider)

open_spider()方法是在Spider开启的时候被自动调用的。在这里我们可以做一些初始化操作,如开启数据库连接等。其中,参数spider就是被开启的Spider对象。

(3) close_spider(spider)

close_spider()方法是在Spider关闭的时候自动调用的。在这里我们可以做一些收尾工作,如 关闭数据库连接等。其中,参数spider就是被关闭的Spider对象。

(4) from_crawler(cls,crawler)

from_crawler()方法是一个类方法,用@classmethod标识,是一种依赖注入的方式。它的参数是crawler,通过crawler对象,我们可以拿到Scrapy的所有核心组件,如全局配置的每个信息,然后创建Pipeline实例。参数cls就是Class,最后返回一个Class实例。

2.2 管道示例

(1) 价格验证和删除没有价格的商品

调整price那些不包含增值税(price_excludes_vat属性)的项目的属性,并删除那些不包含价格的项目:

fromscrapy.exceptionsimportDropItem

classPricePipeline(object):

vat_factor=1.15

defprocess_item(self,item,spider):

ifitem.get('price'):

ifitem.get('price_excludes_vat'):

item['price']=item['price']*self.vat_factor

returnitem

else:

raiseDropItem("Missing price in %s"%item)

(2) 将项目写入JSON文件

将所有已删除的项目存储到一个items.json文件中,每一行包含一个以JSON格式序列化的项目:

importjson

classJsonWriterPipeline(object):

defopen_spider(self,spider):

self.file=open('items.json','w')

defclose_spider(self,spider):

self.file.close()

defprocess_item(self,item,spider):

line=json.dumps(dict(item))+"\n"

self.file.write(line)

returnitem

(3) 将项目写入MongoDB

在这个例子中,我们将使用pymongo将项目写入MongoDB。MongoDB地址和数据库名称在Scrapy设置中指定;MongoDB集合以item类命名。

importpymongo

classMongoPipeline(object):

collection_name='scrapy_items'

def__init__(self,mongo_uri,mongo_db):

self.mongo_uri=mongo_uri

self.mongo_db=mongo_db

@classmethod

deffrom_crawler(cls,crawler):

returncls(

mongo_uri=crawler.settings.get('MONGO_URI'),

mongo_db=crawler.settings.get('MONGO_DATABASE','items')

)

defopen_spider(self,spider):

self.client=pymongo.MongoClient(self.mongo_uri)

self.db=self.client[self.mongo_db]

defclose_spider(self,spider):

self.client

 类似资料: