item Pipeline

item Pipeline及自带图片下载

当item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对item的处理

以下是item pipeline的一些典型应用:

清理HTML数据
验证爬取的数据(检查item包含某些字段)
查重(并丢弃)
将爬取结果保存到数据库中
每个item pipeline组件是一个独立的python类,同时必须实现以下方法:

process_item(item,spider)

每个item pipeline组件都需要调用该方法,这个方法必须返回一个item(或任何继承类)对象,或是抛出DropItem异常,被丢弃的item将不会被之后的pipline组件所处理

参数:item(item对象)-被爬取的item
    spider(Spider对象)-爬取该item的spider

另外还有如下几个比较使用的方法:
open_spider(spider)
close_spider(spider)
from_crawler(cls,crawler)

Item pipeline样例

验证价格,同时丢弃没有价格的item

from scrapy.exceptions import DropItem

class PricePipeline(object):

    vat_factor = 1.15

    def process_item(self, item, spider):
        if item['price']:
            if item['price_excludes_vat']:
                item['price'] = item['price'] * self.vat_factor
            return item
        else:
            raise DropItem("Missing price in %s" % item)

将item写入JSON文件

以下pipeline将所有爬取到的item,存储到一个独立的item.jl文件,每行包含一个序列化为JSON格式的item

import json

class JsonWritePipeline(object):
    def __init__(self):
        self.file = open('item.jl','wb')

    def process_item(self,item,spider):
        line = json.dumps(dict(item))+"/n"
        self.file.write(line)
        return item

去重

一个用于去重的过滤器,丢弃那些已经被处理过的item。让我们假设我们的item有一个唯一的id,但我们spider返回的多个item中包含相同的id
from scrapy.exceptions import DropItem

class DuplicatesPipeline(object):
    def __init__(self):
        self.ids_seen = set()

    def process_item(self,item,spider):
        if item['id'] in self.ids_seen:
            raise DropItem("Duplicate item found:%s"%item)
        else:
            self.ids_seen.add(item['id'])
            return item

启动一个Item Pipeline组件

ITEM_PIPELINES = {
    'myproject.pipelines.PricePipeline': 300,
    'myproject.pipelines.JsonWriterPipeline': 800,
}

Pipeline自带图片下载管道

from scrapy.pipelines.images import ImagesPipeline

#修改自带管道部分属性
class ImagePipeline(ImagesPipeline):
    def file_path(self,request,response=None,info=None):
        url = request.url
        file_name=url.split('/')[-1]
        return file_name

    def item_completed(self,results,item,info):
        image_paths=[x['path'] for ok,x in results if ok]
        if not image_paths:
            raise DropItem('Image Downloaded Failed')
        return item

    def get_media_requests(self,item,info):
        yield Request(item['url'])

你可能感兴趣的:(爬虫)