scrapy框架之item pipeline的使用

一、关于scrapypipleline的基本认识

Item Pipeline又称之为管道,顾名思义就是对数据的过滤处理,其主要的作用包括如下:

  • 清理HTML数据。
  • 验证爬取数据,检查爬取字段。
  • 查重并丢弃重复内容。
  • 将爬取结果保存到数据库。

二、几个核心的方法

创建一个项目的时候都会自带pipeline其中就实现了process_item(item, spider)方法

  • 1、open_spider(spider)就是打开spider时候调用的
  • 2、close_spider(spider)关闭spider时候调用
  • 3、from_crawler(cls, crawler)一般用来从settings.py中获取常量的
  • 4、process_item(item, spider)是必须实现的,别的都是选用的

三、几个常用方法的介绍

  • 1、process_item(item, spider)参数介绍
    • item是要处理的item对象
    • spider当前要处理的spider对象
  • 2、process_item(item, spider)返回值
    • 返回item就会继续给优先级低的item pipeline二次处理
    • 如果直接抛出DropItem的异常就直接丢弃该item
  • 3、open_spider(spider)是在开启spider的时候触发的,常用于初始化操作(常见开启数据库连接,打开文件)
  • 4、close_spider(spider)是在关闭spider的时候触发的,常用于关闭数据库连接
  • 5、from_crawler(cls, crawler)是一个类方法(需要使用@classmethod装饰器标识),常用于从settings.py获取配置信息

关于上面几个方法的使用情况可以参考传送门

四、使用item pipeline爬取网上图片下载到本地介绍

Scrapy提供了专门处理下载的Pipeline,包括文件下载和图片下载。下载文件和图片的原理与抓取页面的原理一样,因此下载过程支持异步和多线程,下载十分高效。下面我们来看看具体的实现过程。官方文档

  • 基本原理

内置ImagesPipeline会默认读取item中图片的url字段,并加入队列中,然后取出没一个url进行图片的下载

五、实现下载图片到本地

  • 1、需要抓取的网页图片https://image.so.com/z?ch=photography,是返回的json,所以我们要抓取的是json数据

  • 2、搭建一个项目

    # 创建一个项目
    scrapy startproject images360
    # 创建一只爬虫
    scrapy genspider images images.so.com
    # 在配置文件中设置
    ROBOTSTXT_OBEY = False
    # 设置编码
    FEED_EXPORT_ENCODING = 'utf-8'
    # 关闭cookie
    COOKIES_ENABLED = False
    # 配置图片存储位置
    IMAGES_STORE = './images'
    
  • 3、管道的书写

    from scrapy import Request
    from scrapy.exceptions import DropItem
    from scrapy.pipelines.images import ImagesPipeline
    
    class ImagePipeline(ImagesPipeline):
        def file_path(self, request, response=None, info=None):
            url = request.url
            file_name = url.split('/')[-1]
            return file_name
    
        def item_completed(self, results, item, info):
            image_paths = [x['path'] for ok, x in results if ok]
            if not image_paths:
                raise DropItem('Image Downloaded Failed')
            return item
    
        def get_media_requests(self, item, info):
            yield Request(item['url'])
    
  • 4、上面方法的介绍

    • 4.1、继承了ImagePipeline(ImagePipelinescrapy内置)
    • 4.2、get_media_requests(item, info)
      • item参数是爬取生成的item对象,从中提取url字段,然后加入到调用队列中,等待下载。

      • info看源码也没解释,打印出来的是

        <scrapy.pipelines.media.MediaPipeline.SpiderInfo object at 0x110e501d0>
        
    • 4.3、file_path(request, response=None, info=None)
      • request表示当前下载对应的request对象(request.__dict__查看属性),该方法用来保存文件名
      • response返回的是None
      • info一样的返回是一个对象(info.__dict__查看)
    • 4.4、item_completed(results, item, info)它是当单个Item完成下载时的处理方法,不是每一张图片都能下载成功,所有要处理
      • results表示下载的结果,返回的是一个列表

        [(True, {'url': 'https://p0.ssl.qhimgs1.com/t01a098025e4214bacc.jpg', 'path': 't01a098025e4214bacc.jpg', 'checksum': '7adb29c836cde7a422c740aac3f86234'})]
        
    • 4.5、定义的管道要在settings.py中配置

五、对下载的图片重命名

  • 1、现在抓取的图片地址是

  • 2、在spiders里面使用分页技术

  • 3、item pipeline中使用meta把参数携带到request

  • 4、在file_path函数中重命名

  • 5、具体的代码

    # 定义一个下载pic图片的管道
    class PicPipeline(ImagePipeline):
        def file_path(self, request, response=None, info=None):
            print('=======', request.__dict__)
            url = request.url
            # 防止有中文重名的特意加上时间鹾
            return '{0}-{1}.{2}'.format(request.meta['title'], str(time.time()).split('.')[0], url.split('.')[-1])
    
        def item_completed(self, results, item, info):
            image_paths = [x['path'] for ok, x in results if ok]
            if not image_paths:
                raise DropItem('Image Downloaded Failed')
            return item
    
        def get_media_requests(self, item, info):
            # 从管道中获取图片的地址
            yield Request(url=item['url'], meta={'title': item['title']})
    

六、总结

  • 1、使用urllib包组装get请求的url

    from urllib.parse import urlencode
    params = urlencode(data)
    
  • 2、抓取的是json数据的处理

    result = json.loads(response.text)
    ...接下来跟之前的一样处理
    

七、查看博主更多文章

你可能感兴趣的:(爬虫)