当 Item 在 Spider 中被收集之后, 就会被传递到 Item Pipeline 中进行处理.
每个 item pipeline 组件是实现了简单的方法的 python 类, 负责接收到 item 并通过它执行一些行为, 同时也决定此 item 是否继续通过 pipeline, 或者被丢弃而不再进行处理.
item pipeline 的主要作用 :
1. 清理 html 数据
2. 验证爬取的数据
3. 去重并丢弃
4. 将爬取的结果保存到数据库中或文件中
编写自己的 item pipeline :
process_item(self, item, spider)
每个 item piple 组件是一个独立的 python 类, 必须实现以 process_item(self, item, spider) 方法
每个 item pipeline 组价都需要调用该方法, 这个方法必须返回一个具有数据的 dict, 或者 item 对象, 或者抛出 DropItem 异常, 被丢弃的 item 将不会被之后的 pipeline 组价所处理
下面的方法也可以选择实现:
open_spider(self, spider)
表示当 spider 被开启的时候调用这个方法
close_spider(self, spider)
当 spider 关闭的时候这个方法被调用
from_crawler(cls, crawler)
这个和在前面说的 spider 用法是一样的, 可以用于获取 settings 配置文件中的信息, 需要注意的此方法是一个类方法, 举个栗子:
一些 item pipeline 的使用例子
栗子 1 :
此栗子是判断 item 中是否包含 price 以及 price_excludes_vat, 如果存在则调整 price 属性, 都让 item["price"] = item["price"] * self.vat_factor, 如果不存在拟则返回 DropItem
- 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)
栗子 2 :
此栗子是将 item 写入到 JSON 文件中
- import JSON
- class JsonWriterPipeline(object):
- def __init__(self):
- self.file = open('items.jl', 'wb')
- def process_item(self, item, spider):
- line = JSON.dumps(dict(item)) + "\n"
- self.file.write(line)
- return item
栗子 3 :
将 item 写入到 MongoDB, 同时演示 from_crawler 用法
- import pymongo
- class MongoPipeline(object):
- collection_name = 'scrapy_items'
- def __init__(self, mongo_uri, mongo_db):
- self.mongo_uri = mongo_uri
- self.mongo_db = mongo_db
- @classmethod
- def from_crawler(cls, crawler):
- return cls(
- mongo_uri=crawler.settings.get('MONGO_URI'),
- mongo_db=crawler.settings.get('MONGO_DATABASE', 'items')
- )
- def open_spider(self, spider):
- self.client = pymongo.MongoClient(self.mongo_uri)
- self.db = self.client[self.mongo_db]
- def close_spider(self, spider):
- self.client.close()
- def process_item(self, item, spider):
- self.db[self.collection_name].insert(dict(item))
- return item
栗子 4 :
一个用于去重的过滤器, 丢弃那些已经被处理过的 item, 假设 item 有一个唯一的 id, 但是 spider 返回的多个 item 中包含了相同的 id, 去重方法如下: 初始化一个集合, 每次判断 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 组件
在 settings 配置文件中有一个 ITEM_PIPELINES 的配置参数 :
- ITEM_PIPELINES = {
- 'myproject.pipelines.PricePipeline': 300,
- 'myproject.pipelines.JsonWriterPipeline': 800,
- }
每个 pipeline 后面有一个数值, 这个数值的范围是 0-1000, 这个数值确定了他们的运行顺序 (即优先级), 数字越小越优先执行.
来源: http://www.bubuko.com/infodetail-2931432.html