9.3-Scrapy框架爬虫【进阶】-Item Pipelines用法

Scrapy提供了Item类

Item对象是种简单的容器(类似于字典(dict,键值对)),保存爬取到得数据

1、声明Item

Item使用简单的class定义语法Filed对象来申明,例如:

from scrapy import Field,Item
class Produce(Item):
    name=Field()
    price=Field()
    stock=Field()

2、Item Pipeline

    当Item被spider抓取后,它被发送到Item管道(Item Pipeline),它通过顺序执行的几个组件来处理Item。

    每个item pipeline组件(有时称为Item Pipeline)是实现了简单方法的python类。他们接收到Item并通过它执行一些行为,同时也决定此Item是否继续通过pipeline,或者被丢弃而不再进行处理。

    以下是Item Pipeline的典型应用:

  • 清洗HTML数据
  • 验证爬取的数据(检查item包含某些字段)
  • 查重(并丢弃)
  • 将爬取结果保存到数据库中

3、编写自己的item pipeline

每个item pipeline组件是一个独立的python类,同时实现以下方法:

(1)process_item(self,item,spider)

    每个Item Pipeline组件都会调用此方法。该方法必须:返回一个带数据的dict,或是返回一个Item(或任何后代类)对象,或是返回一个Twisted Deffered,或者抛出异常。被抛弃的Item不再被其他的Ppipeline组件处理。

参数:

  • item (Item对象或一个dict)----->被爬取的item
  • spider (Spider对象)----->爬取该item的spider

(2)open_spider(self,spider)

当spider被开启时,这个方法被调用。

参数:

  • spider (Spider对象)----->被开启的spider

(3)close_spider(self,spider)

当spider被关闭时,这个方法被调用。

参数:

  • spider (Spider对象)----->被关闭的spider

(4)from_crawl(cls,crawler)

如果存在,则调用此方法以从crawler创建pipeline实例。它必须返回一个新的pipeline实例。

crawler对象提供所有scrapy核心组件(如settings和signals)的访问,它是pipeline访问它们并将其功能挂钩到scrapy的一种方法。

参数:

  • crawler (Crawler对象)----->使用此pipeline的crawler

4、Item Pipeline示例(在pipelines.py中编辑)

(4-1)验证价格,同时丢弃没有价格的item

说明:其调整了不包括增值税(price_excludes_vat属性)的那些item的price属性,并丢弃那些不包含price的item

from scrapy.exceptions import DropItem
class PriceItem(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 {}".format(item))

(4-2)将item写入.json文件

说明:其将所有(从所有spider中)爬取到的item存储到一个独立的info.jl文件,每行包含一个序列化为json格式的item

import json
class JsonWriterPipeline(object):
    def __init__(self):
        self.filename=open('info.json','a',encoding='utf-8')
    
    def process_item(self,item,spider):
        line=json.dumps(dict(item),ensure_ascii=False)
        self.filename.write(line)
        self.filename.write('\n')
    
    def close_spider(self,spider):
        self.filename.close()

(4-3)将item写入MongoDB数据库

说明:其将使用pymongo将item写入MongoDB。MongoDB中的配置在scrapy的settings.py中指定

假设settings.py中的配置如下:

ITEM_PIPELINES={'quotes.pipelines.QuotesPipeline':300,}
MONGODB_HOST='127.0.0.1' #主机号
MONGODB_PORT=27017  #端口号
MONGODB_DBNAME='Quotes' #数据库名
MONGODB_SHEETNAME='mymj' #表名

pipelines.py中操作:将item数据保存到数据库中

from scrapy.conf import settings
import pymongo
class QuotesPipelines(object):
    def __init__(self):
        self.host=settings['MONGODB_HOST']
        self.port=settings['MONGODB_PORT']
        self.dbname=settings['MONGODB_DBNAME']
        self.sheetname=settings['MONGODB_SHEETNAME']
        client=pymongo.MongoClient(host=self.host,port=self.port)
        mydb=client[self.dbname]
        self.post=mydb[self.sheetname]
    def process_item(self,item,spider):
        data=dict(item)
        self.post.insert(data)  #将数据存入到mongodb数据库中
        return item

(4-4)去重

说明:用于查找重复的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("去重的item为{}".format(item))
        else:
            self.ids_seen.add(item['id'])
            return item

5、激活一个Item Pipeline组件

要激活item pipeline,必须将其类添加到ITEM_PIPELINES设置中,如下:

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

在此设置中分配给类的整数值确定它们运行的顺序:item按数字从低到高的顺序通过pipeline。【数字越低优先级越高】

转载于:https://my.oschina.net/pansy0425/blog/3093043

你可能感兴趣的:(9.3-Scrapy框架爬虫【进阶】-Item Pipelines用法)