当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理。
每个item pipeline组件(有时称之为“Item Pipeline”)是实现了简单方法的Python类。他们接收到Item并通过它执行一些行为,同时也决定此Item是否继续通过pipeline,或是被丢弃而不再进行处理。
以下是item pipeline的一些典型应用:
- 清理HTML数据
- 验证爬取的数据(检查item包含某些字段)
- 查重(并丢弃)
- 将爬取结果保存到数据库中
这一次我们要通过Item Pipeline实现对Item中URL的修改
一、修改one_spider.py的内容,此处要注意yield item,否则item pipeline不生效。
class SamSpider(scrapy.Spider):
name = "sam"
start_urls = [
"https://maoyan.com/board/4"
]
url = 'https://maoyan.com/board/4'
def parse(self, response):
for sel in response.xpath('//*[@id="app"]/div/div/div/dl/dd'):
item = SamzhuItem()
item['name'] = sel.xpath('div/div/div[1]/p[1]/a/@title').extract()[0]
item['url'] = sel.xpath('div/div/div[1]/p[1]/a/@href').extract()[0]
yield item
print('>'*50,'获取下一页请求')
a=response.css('.list-pager li:last-child a::attr(href)').extract()[0] #选择到‘下一页’的按钮
if re.search(r'offset',a,re.M|re.I)!=None:
print('换页成功')
yield scrapy.Request(self.url+a, callback=self.parse) #返回一个requset,设置callback函数为parse
print('+'*50)
else:
print('到达终点')
二、修改pipelines.py文件
class SamzhuPipeline(object):
url ='https://maoyan.com'
def process_item(self, item, spider):
#在这里可以处理item中的信息
item['url']=self.url+item['url']
return item
三、修改settings.py文件
ITEM_PIPELINES = {
#数字代表优先度,越小优先度越高
'samzhu.pipelines.SamzhuPipeline': 300
}
此时我们已经可以实现对Item中的url进行增加
我们再尝试讲数据写到数据库中去。
四、在pipelines.py中添加新的item pipeline组件
import pymongo
class MongoPipeline(object):
def process_item(self, item, spider):
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["sam"]
mycol = mydb["scrapy"]
mycol.insert_one(item.ToDict())
return item
其中的item.ToDict()如下,通过修改items.py使得item的类方法的调用使得Item类可以返回一个dict,方便写入数据库
import scrapy
class SamzhuItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
name = scrapy.Field()
url = scrapy.Field()
def ToDict(self):
return {'name':self['name'],'url':self['url']}
再修改settings.py,写入mongodb的优先级低于修改item
ITEM_PIPELINES = {
'samzhu.pipelines.SamzhuPipeline': 300,
'samzhu.pipelines.MongoPipeline': 400
}