Python爬虫学习笔记 2-2:Scrapy项目管道

Published On 2019/11/16 Sunday, Singapore

上一节,我们了解到scrapy框架,安装和基本使用。其中提到了项目管道的主要作用包括清洗验证数据,检查重复并删除,数据入库。这一节,我们讲解scrapy的项目管道的使用。

本文为Datacatsle Python爬虫(入门+进阶)课程学习笔记。


项目管道的主要函数

process_item(self, item, spider): 每个item pipeline组件都需要调用该方法,这个方法必须返回一个item对象,或是抛出DropItem异常,被丢弃的item将不会被之后的 pipeline组件所处理。需要传入的参数为:

该方法会被每一个item pipeline组件所调用,必须返回一个以下任意对象



例1: 通过项目管道实现调整不包括增值税(price_excludes_vat)项目价格,并删除不包含价格的项目。

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: #如果没有价格,则抛弃这个item
            raise DropItem("Missing price in %s" % item)



例2:通过项目管道实现查找重复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):
        #查看id是否在ids_seen中,如果在,就抛弃该Item,如果不在就添加到ids_seen中,下一次其它Item有相同的id就抛弃那个Item
        if item['id'] in self.ids_seen:
            raise DropItem("Duplicate item found: %s" % item)
        else:
            self.ids_seen.add(item['id'])
            return item #记住一定要返回Item

open_spider(self, spider):当spider被开启时,这个方法被调用。可以实现在爬虫开启时需要进行的操作,比如说打开一个待写入的文件,或者连接数据库等。

close_spider(self, spider): 当spider被关闭时,这个方法被调用。可以实现在爬虫关闭时需要进行的操作,比如说关闭已经写好的文件,或者关闭与数据库的连接。



例3:将所有抓取的item存储到单个items.json文件中,以JSON格式序列化:

import json
class JsonWriterPipeline(object):
    def open_spider(self, spider):
        #在爬虫开始时打开文件
        self.file = open('items.json', 'w')

    def close_spider(self, spider):
        #在爬虫结束时关闭文件
        self.file.close()

    def process_item(self, item, spider):
        #把爬取到的item转换为json格式,保存进文件
        line = json.dumps(dict(item)) + "\n"
        self.file.write(line)
        return item #注意要返回item

from_crawler(cls, crawler):该类方法用来从crawler中初始化得到一个 pipeline实例;它必须返回一个新的pipeline实例;crawler对象提供了访问所有scrapy核心组件的接口,包括settings和signals。



例4:使用pymongo将项目写入MongoDB。MongoDB地址和数据库名称在Scrapy设置中指定; MongoDB集合以item类命名。from_crawler()方法是创建通往crawler的pipeline,返回一个新的pipeline实例。这个例子的要点是显示如何使用from_crawler()方法和如何正确清理资源。通过类方法from_crawler()在内部初始化得到了一个 pipeline实例,初始化的过程中,使用了mongo_uri以及 mongo_db作为构造参数

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_one(dict(item))
        return item

案例:爬取58同城出租房信息(一)

现在我们要爬取58同城出租房第一页信息,包括:出租信息名称,详情页链接和价格。

步骤如下:





💚 Back to Home