Scrapy框架之利用ImagesPipeline下载图片

简介: 1.ImagesPipeline简介 Scrapy用ImagesPipeline类提供一种方便的方式来下载和存储图片。

1.ImagesPipeline简介

Scrapy用ImagesPipeline类提供一种方便的方式来下载和存储图片。

特点:

  • 将下载图片转换成通用的JPG和RGB格式
  • 避免重复下载
  • 缩略图生成
  • 图片大小过滤

2.ImagesPipeline工作流程

当使用图片管道 ImagePipeline,典型的工作流程如下:

  • 在一个爬虫里,你抓取一个项目,把其中图片的URL放入image_urls组内。
  • 项目从爬虫内返回,进入项目管道。
  • 当项目进入ImagePipeline, image_urls组内的URLs将被Scrapy的调度器和下载器安排下载(这意味着调度器和中间件可以复用),当优先级更高,会在其他页面被抓取前处理. 项目会在这个特定的管道阶段保持”locker”的状态,直到完成图片的下载(或者由于某些原因未完成下载)。
  • 当图片下载完, 另一个组(images)将被更新到结构中,这个组将包含一个字典列表,其中包括下载图片的信息,比如下载路径,源抓取地址(从image_urls组获得)和图片的校验码. images列表中的图片顺序将和源image_urls组保持一致.如果某个图片下载失败,将会记录下错误信息,图片也不会出现在images组中。

3.操作过程

项目目录结构:

这里写图片描述

要想成功爬取图片,需要经过以下几个步骤:

(1)在items.py中添加image_urls、images和image_paths字段,代码如下:

class DoubanImgsItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    image_urls = Field()
    images = Field()
    image_paths = Field()

(2)在settings.py中设置条件和属性,代码如下:

# Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html

# ImagePipeline的自定义实现类
ITEM_PIPELINES = {
    'douban_imgs.pipelines.DoubanImgDownloadPipeline': 300,
}
#设置图片下载路径
IMAGES_STORE = 'D:\\doubanimgs'
# 过期天数
IMAGES_EXPIRES = 90  #90天内抓取的都不会被重抓

(3)在spiders/download_douban.py中书写ImageSpider的代码:

# coding=utf-8
from scrapy.spiders import Spider
import re
from scrapy import Request
from ..items import DoubanImgsItem


class download_douban(Spider):
    name = 'download_douban'

    default_headers = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
        'Accept-Encoding': 'gzip, deflate, sdch, br',
        'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6',
        'Cache-Control': 'max-age=0',
        'Connection': 'keep-alive',
        'Host': 'www.douban.com',
        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36',
    }

    def __init__(self, url='1638835355', *args, **kwargs):
        self.allowed_domains = ['douban.com']
        self.start_urls = [
            'http://www.douban.com/photos/album/%s/' % (url)]
        self.url = url
        # call the father base function

        # super(download_douban, self).__init__(*args, **kwargs)

    def start_requests(self):

        for url in self.start_urls:
            yield Request(url=url, headers=self.default_headers, callback=self.parse)

    def parse(self, response):
        list_imgs = response.xpath('//div[@class="photolst clearfix"]//img/@src').extract()
        if list_imgs:
            item = DoubanImgsItem()
            item['image_urls'] = list_imgs
            yield item

(4)在pipelines.py中自定义ImagePipeline代码:

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
from scrapy.pipelines.images import ImagesPipeline
from scrapy.exceptions import DropItem
from scrapy import Request
from scrapy import log


class DoubanImgsPipeline(object):
    def process_item(self, item, spider):
        return item


class DoubanImgDownloadPipeline(ImagesPipeline):
    default_headers = {
        'accept': 'image/webp,image/*,*/*;q=0.8',
        'accept-encoding': 'gzip, deflate, sdch, br',
        'accept-language': 'zh-CN,zh;q=0.8,en;q=0.6',
        'cookie': 'bid=yQdC/AzTaCw',
        'referer': 'https://www.douban.com/photos/photo/2370443040/',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36',
    }

    def get_media_requests(self, item, info):
        for image_url in item['image_urls']:
            self.default_headers['referer'] = image_url
            yield Request(image_url, headers=self.default_headers)

    def item_completed(self, results, item, info):
        image_paths = [x['path'] for ok, x in results if ok]
        if not image_paths:
            raise DropItem("Item contains no images")
        item['image_paths'] = image_paths
        return item

在自定义ImagePipeline代码中,作为重要的是要重载get_media_requests(self, item, info)item_completed(self, results, item, info)这两个函数。

  • get_media_requests(self,item, info):

ImagePipeline根据image_urls中指定的url进行爬取,可以通过get_media_requests为每个url生成一个Request。如:

for image_url in item['image_urls']:
            self.default_headers['referer'] = image_url
            yield Request(image_url, headers=self.default_headers)
  • item_completed(self, results, item, info):

图片下载完毕后,处理结果会以二元组的方式返回给item_completed()函数。这个二元组定义如下:

(success, image_info_or_failure)

其中,第一个元素表示图片是否下载成功;第二个元素是一个字典。如:

 def item_completed(self, results, item, info):
        image_paths = [x['path'] for ok, x in results if ok]
        if not image_paths:
            raise DropItem("Item contains no images")
        item['image_paths'] = image_paths
        return item

4.爬取结果

运行结果如下:

这里写图片描述

下载成功以后,你就会在刚才设置的保存图片的路径里看到下载完成的图片:IMAGES_STORE = ‘D:\doubanimgs’

这里写图片描述


5.扩展

默认情况下,使用ImagePipeline组件下载图片的时候,图片名称是以图片URL的SHA1值进行保存的。

如:
图片URL:http://www.example.com/image.jpg
SHA1结果:3afec3b4765f8f0a07b78f98c07b83f013567a0a
则图片名称:3afec3b4765f8f0a07b78f98c07b83f013567a0a.jpg

如果想进行更改,请参考:使用scrapy框架的ImagesPipeline下载图片如何保持原文件名呢?


相关文章
|
4月前
|
数据采集 存储 机器人
Scrapy网络爬虫框架——从入门到实践
网络爬虫已经成为了信息获取的必备工具之一,而Scrapy作为Python中最流行的网络爬虫框架之一,具有高效、可扩展、易用等特点。本文将深入介绍Scrapy框架的概念和实践,帮助读者快速掌握构建高质量网络爬虫的方法。
75 0
|
4月前
|
数据采集 存储 调度
Scrapy:从入门到实践的网络爬虫框架
Scrapy是一款强大的Python网络爬虫框架,可以帮助开发者更高效地抓取互联网上的数据。本文将介绍Scrapy的概念和基本原理,详细讲解如何使用Scrapy框架实现一个简单的网络爬虫,并分享一些实战经验和技巧。
|
4月前
|
数据采集 存储 调度
Scrapy:高效的Python网络爬虫框架
在信息时代,数据的获取和分析已经成为了一项重要的技能。而网络爬虫则是实现数据采集的一种常用手段。Scrapy作为一个高效、灵活的Python网络爬虫框架,其具备强大的扩展性、高度的可配置性以及良好的兼容性。本文将从Scrapy的概念入手,介绍其基本原理、使用方法以及实际应用案例。
|
4月前
|
人工智能 自然语言处理 Python
Scrapy框架 -- 结合百度AI实现文本处理
Scrapy框架 -- 结合百度AI实现文本处理
18 0
|
4月前
|
数据采集 中间件 Python
Scrapy框架 -- 结合selenium获取动态加载数据
Scrapy框架 -- 结合selenium获取动态加载数据
22 0
|
4月前
|
数据采集 中间件 Python
Scrapy框架 -- 中间件介绍
Scrapy框架 -- 中间件介绍
19 0
|
4月前
|
数据采集 Python
Scrapy框架 -- POST请求实现案例
Scrapy框架 -- POST请求实现案例
14 0
|
4月前
|
数据采集 存储 数据处理
Scrapy:Python网络爬虫框架的利器
在当今信息时代,网络数据已成为企业和个人获取信息的重要途径。而Python网络爬虫框架Scrapy则成为了网络爬虫工程师的必备工具。本文将介绍Scrapy的概念与实践,以及其在数据采集和处理过程中的应用。
24 1
|
5月前
|
数据采集 调度 Python
Scrapy爬虫中合理使用time.sleep和Request
Scrapy爬虫中合理使用time.sleep和Request
|
8天前
|
数据采集 存储 中间件
【专栏】Scrapy:解锁网络爬虫新境界
【4月更文挑战第27天】Scrapy是Python的高效爬虫框架,以其异步处理、多线程和中间件机制提升爬取效率。它的灵活性体现在可定制化组件、支持多种数据库存储及与Selenium、BeautifulSoup等工具集成。Scrapy易于扩展,允许自定义下载器和解析器。在实践中,涉及项目配置、Spider类编写、数据抓取、存储与分析。面对动态网页和反爬机制,Scrapy可通过Selenium等工具应对,但需注意法规与道德规范。随着技术发展,Scrapy将在网络爬虫领域持续发挥关键作用。