Scrapy 简明教程

Scrapy - Item Pipeline

Description

Item Pipeline 是一种对收集到的项目进行处理的方法。当一个项目被发送到项目管道时,它会被一个爬虫程序抓取出来,然后使用几个按顺序执行的组件进行处理。

每当接收到一个项目时,就会决定采取以下两种操作之一 −

  1. Keep processing the item.

  2. Drop it from pipeline.

  3. Stop processing the item.

项目管道通常用于以下目的 −

  1. 将抓取到的项目存储在数据库中。

  2. 如果接收到的项目是一个重复的项目,那它会将重复的项目删除。

  3. 它将检查该项目是否带有目标字段。

  4. Clearing HTML data.

Syntax

您可以使用以下方法编写项目管道 −

process_item(self, item, spider)

上述方法包含以下参数 −

  1. Item (Item 对象或字典)- 它指定要抓取的 Item。

  2. spider (spider 对象)- 发送该 Item 的 spider。

你也可以使用下表中给出的各种方法-

Sr.No

Method & Description

Parameters

1

open_spider(self, spider) 当 spider 被打开时选择它。

spider(spider 对象)- 它指被打开的 spider。

2

close_spider(self, spider) 当 spider 被关闭时选择它。

spider (spider 对象)- 它指被关闭的 spider。

3

from_crawler(cls, crawler) 借助 crawler, 该管道可以访问 Scrapy 的核心组件,如信号和设定。

crawler (Crawler 对象)- 它指使用此管道的 crawler。

Example

以下是用于不同概念的 Item 管道的范例。

Dropping Items with No Tag

在以下代码中,管道平衡了那些不包含增值税(excludes_vat 属性)的 Item 的(price)属性并忽略不带价签的 Item.-

from Scrapy.exceptions import DropItem
class PricePipeline(object):
   vat = 2.25

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

Writing Items to a JSON File

以下代码将把所有 spider 抓取的所有 Item 存储到单个 items.jl 文件中,其中包含每个以 JSON 格式序列化的行里的一个 Item。 JsonWriterPipeline 类在代码中用于展示如何编写 Item 管道-

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

Writing Items to MongoDB

你可以在 Scrapy 设置中指定 MongoDB 地址和数据库名称,并且 MongoDB 集合可以以 Item 类命名。以下代码描述了如何正确使用 from_crawler() 方法来收集资源-

import pymongo

class MongoPipeline(object):
   collection_name = 'Scrapy_list'

   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_DB', 'lists')
      )

   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

Duplicating Filters

过滤器会检查重复的 Item, 并且会删除已经处理的 Item。在以下代码中,我们为我们的 Item 已经使用一个唯一的 id, 但是 spider 返回了多个带有相同 id 的 Item -

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("Repeated items found: %s" % item)
      else:
         self.ids_seen.add(item['id'])
         return item

Activating an Item Pipeline

你可以通过将它的类添加到 ITEM_PIPELINES 设置中来激活一个 Item Pipeline 组件,如下面的代码所示。你可以按照它们运行的顺序给类分配整数值(顺序可以从低值到高值),并且其值在 0 到 1000 范围内。

ITEM_PIPELINES = {
   'myproject.pipelines.PricePipeline': 100,
   'myproject.pipelines.JsonWriterPipeline': 600,
}