• Scrapy爬虫框架第七讲【ITEM PIPELINE用法】


    ITEM PIPELINE用法详解

     

     ITEM PIPELINE作用:

    • 清理HTML数据
    • 验证爬取的数据(检查item包含某些字段)
    • 去重(并丢弃)【预防数据去重,真正去重是在url,即请求阶段做】
    • 将爬取结果保存到数据库中


     ITEM PIPELINE核心方法(4个)

    (1)、open_spider(spider)

    (2)、close_spider(spider)

    (3)、from_crawler(cls,crawler)

    (4)、process_item(item,spider)

    下面小伙伴们我们依次来分析:

    1、open_spider(spider) 【参数spider 即被开启的Spider对象】

    该方法非必需,在Spider开启时被调用,主要做一些初始化操作,如连接数据库等

    2、close_spider(spider)【参数spider 即被关闭的Spider对象】

    该方法非必需,在Spider关闭时被调用,主要做一些如关闭数据库连接等收尾性质的工作

    3、from_crawler(cls,crawler)【参数一:Class类 参数二:crawler对象】

    该方法非必需,Spider启用时调用,早于open_spider()方法,是一个类方法,用@classmethod标识,它与__init__函有关,这里我们不详解(一般我们不对它进行修改)

    4、process_item(item,spider)【参数一:被处理的Item对象 参数二:生成该Item的Spider对象】

    该方法必需实现,定义的Item pipeline会默认调用该方法对Item进行处理,它返回Item类型的值或者抛出DropItem异常


    实例分析(以下实例来自官网:https://doc.scrapy.org/en/latest/topics/item-pipeline.html)

     1 from scrapy.exceptions import DropItem
     2 
     3 class PricePipeline(object):
     4 
     5     vat_factor = 1.15
     6 
     7     def process_item(self, item, spider):
     8         if item['price']:
     9             if item['price_excludes_vat']:
    10                 item['price'] = item['price'] * self.vat_factor
    11             return item
    12         else:
    13             raise DropItem("Missing price in %s" % item)

    代码分析:

    首先定义了一个PricePipeline类

    定义了增值税税率因子为1.15

    主函数process_item方法实现了如下功能:判断Item中的price字段,如没计算增值税,则乘以1.15,并返回Item,否则直接抛弃

    总结:该方法要么return item给后边的管道处理,要么抛出异常


     数据去重

     1 from scrapy.exceptions import DropItem
     2 
     3 class DuplicatesPipeline(object):
     4 
     5     def __init__(self):
     6         self.ids_seen = set()
     7 
     8     def process_item(self, item, spider):
     9         if item['id'] in self.ids_seen:
    10             raise DropItem("Duplicate item found: %s" % item)
    11         else:
    12             self.ids_seen.add(item['id'])
    13             return item

    代码分析:

    首先定义了一个DuplicatesPipeline类

    这里比上面多了一个初始化函数__init__,set()---去重函数

    主函数process_item方法首先判断item数据中的id是否重复,重复的就将其抛弃,否则就增加到id,然后传给下个管道


     将数据写入文件

     1 import json
     2 
     3 class JsonWriterPipeline(object):
     4 
     5     def open_spider(self, spider):
     6         self.file = open('items.jl', 'w')
     7 
     8     def close_spider(self, spider):
     9         self.file.close()
    10 
    11     def process_item(self, item, spider):
    12         line = json.dumps(dict(item)) + "
    "
    13         self.file.write(line)
    14         return item

    代码分析:

    首先我们定义了一个JsonWritePipeline类

    定义了三个函数:

    first:open_spider()在Spider开启时启用作用很简单即打开文件,准备写入数据

    second:close_spider()在Spider关闭时启用作用也很简单即关闭文件

    third(主要):process_items()作用如下首先将item转换为字典类型,在用json.dumps()序列化为json字符串格式,再写入文件,最后返回修改的item给下一个管道


    综合实例

     1 import pymongo
     2 
     3 class MongoPipeline(object):
     4 
     5     collection_name = 'scrapy_items'
     6 
     7     def __init__(self, mongo_uri, mongo_db):
     8         self.mongo_uri = mongo_uri
     9         self.mongo_db = mongo_db
    10 
    11     @classmethod
    12     def from_crawler(cls, crawler):
    13         return cls(
    14             mongo_uri=crawler.settings.get('MONGO_URI'),
    15             mongo_db=crawler.settings.get('MONGO_DATABASE', 'items')
    16         )
    17 
    18     def open_spider(self, spider):
    19         self.client = pymongo.MongoClient(self.mongo_uri)
    20         self.db = self.client[self.mongo_db]
    21 
    22     def close_spider(self, spider):
    23         self.client.close()
    24 
    25     def process_item(self, item, spider):
    26         self.db[self.collection_name].insert(dict(item))
    27         return item

    代码分析:

    首先我们定义了一个MongoPipeline类

    这里我们修改了初始化函数__init__,给出了存储到Mongodb的链接地址和数据库名称所以更改了from_crawler()工厂函数函数(生产它的对象),这里指定了链接地址和数据表名称

    最后我们定义了三个函数:

    first:open_spider()在Spider开启时启用作用是打开mongodb数据库

    second:close_spider()在Spider关闭时启用作用是关闭数据库

    third:process_items()作用如下在数据库中插入item


    项目实战:(我们以58同城镇江房屋出租为例)抓取出租信息的标题、价格、详情页的url

    我是在ubuntu16.04环境下跑的

    启动终端并激活虚拟环境:source course_python3.5/bin/activate

    创建一个新目录project:mkdir project

    创建项目:scrapy startproject city58-----cd city58----创建爬虫(这里小伙伴们注意项目名不能与爬虫名重名)scrapy genspider city58_test

    下面我们正式开始

    (1)、修改items.py

    (2)修改city58_test.py文件(这里我们使用pyquery选择器)

    (3)、重点来了,修改pipelines.py文件,小伙伴们可参考上面的案例分析

    (4)最后通过settings.py启动pipeline

    这里向小伙伴们科普一个小知识点:后面的数字是优先级,数字越小,越优先执行

    (5)项目运行结果(部分)----下次小伙伴们想了解出租信息可以找我,我帮你秒下。哈哈!

    并且我们可以在同级目录下找到我们写入的文件

    总结:

    (1)、首先了解了管道的作用

    (2)、掌握了核心的方法,其中特别是process_item()方法

    (3)、最后我们通过实例和项目进行实战,后面我们会继续学习如何使用管道进行高级的操作,敬请期待,记得最后一定要在配置文件中开启Spider中间件

  • 相关阅读:
    论 IntStream 和 for 循环的速度
    单链线性表的基本操作--创建,插入,删除,查看,打印
    Android中的异步处理方式
    Kotlin 集合变换与序列
    Kotlin Lazy延迟初始化
    协程及Kotlin协程
    Java 注解
    Android 事件传递机制进阶
    Java 异常
    Java 多线程及线程间通信(Synchronized和Volatile关键字)
  • 原文地址:https://www.cnblogs.com/518894-lu/p/9053939.html
Copyright © 2020-2023  润新知