Scrapy - 项目管道



描述

项目管道 (Item Pipeline) 是一种处理爬取到的数据项的方法。当一个数据项被发送到项目管道时,它已经由爬虫爬取,并通过多个依次执行的组件进行处理。

每当接收到一个数据项,管道会决定以下其中一种操作:

  • 继续处理数据项。
  • 从管道中丢弃数据项。
  • 停止处理数据项。

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

  • 将爬取的数据项存储到数据库。
  • 如果接收到重复的数据项,则会丢弃重复项。
  • 检查数据项是否包含目标字段。
  • 清除HTML数据。

语法

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

process_item(self, item, spider) 

上述方法包含以下参数:

  • Item (数据项对象或字典) - 指定爬取到的数据项。
  • spider (爬虫对象) - 爬取该数据项的爬虫。

您可以使用下表中列出的其他方法:

序号 方法 & 描述 参数
1

open_spider(self, spider)

在爬虫打开时调用。

spider (爬虫对象) - 指的是被打开的爬虫。

2

close_spider(self, spider)

在爬虫关闭时调用。

spider (爬虫对象) - 指的是被关闭的爬虫。

3

from_crawler(cls, crawler)

通过爬虫对象,管道可以访问Scrapy的核心组件,例如信号和设置。

crawler (爬虫对象) - 指的是使用此管道的爬虫。

示例

以下是项目管道在不同场景中的示例。

丢弃没有标签的数据项

在下面的代码中,管道会为那些不包含增值税 (excludes_vat 属性) 的数据项平衡 (price) 属性,并忽略那些没有价格标签的数据项:

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) 

将数据项写入 JSON 文件

下面的代码会将所有爬虫爬取到的数据项存储到单个 items.jl 文件中,该文件每行包含一个以 JSON 格式序列化的数据项。代码中使用了 JsonWriterPipeline 类来演示如何编写项目管道:

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

将数据项写入 MongoDB

您可以在 Scrapy 设置中指定 MongoDB 地址和数据库名称,MongoDB 集合可以根据数据项类命名。下面的代码描述了如何使用 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

重复项过滤

过滤器会检查重复的数据项,并丢弃已处理的数据项。在下面的代码中,我们为数据项使用了唯一的 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("Repeated items found: %s" % item) 
      else: 
         self.ids_seen.add(item['id']) 
         return item

激活项目管道

您可以通过将项目管道的类添加到 ITEM_PIPELINES 设置中来激活它,如下面的代码所示。您可以为类分配整数来指定它们的执行顺序(顺序可以是从较低值到较高值的类),值范围为 0-1000。

ITEM_PIPELINES = {
   'myproject.pipelines.PricePipeline': 100,
   'myproject.pipelines.JsonWriterPipeline': 600,
}
广告
© . All rights reserved.