Python Scrapy 图片下载 ImagesPipeline

参考

1.创建项目

scrapy startproject ImagesRename

2.编写 item

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

import scrapy

class ImagesrenameItem(scrapy.Item):
    imgurl = scrapy.Field()
    imgname = scrapy.Field()
    pass

3.spiders目录下创建蜘蛛文件:ImgsRename.py编写相应蜘蛛

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

import scrapy
from ImagesRename.items import ImagesrenameItem

class ImgsrenameSpider(scrapy.Spider):
    name = 'ImgsRename'
    allowed_domains = ['lab.scrapyd.cn']
    start_urls = [
        'http://lab.scrapyd.cn/archives/55.html',
        'http://lab.scrapyd.cn/archives/57.html',
        ]

    def parse(self, response):
        item = ImagesrenameItem()
        # 注意imgurls是一个集合也就是多张图片
        item['imgurl'] = response.css(".post img::attr(src)").extract()
        # 抓取文章标题作为图集名称
        item['imgname'] = response.css(".post-title a::text").extract_first()
        yield item

这里并没有使用

scrapy genspider xxxxx xxxxxxxx.com

来创建默认爬虫,因为不能够创建到与项目同名的爬虫。

4.编写 pipeline

import re
from scrapy.pipelines.images import ImagesPipeline
from scrapy import Request

class ImagesrenamePipeline(ImagesPipeline):
    def get_media_requests(self, item, info):
        # 循环每一张图片地址下载,若传过来的不是集合则无需循环直接yield
        for image_url in item['imgurl']:
            # meta里面的数据是从spider获取,然后通过meta传递给下面方法:file_path
            yield Request(image_url,meta={'name':item['imgname']})
    
    # 重命名,若不重写这函数,图片名为哈希,就是一串乱七八糟的名字
    def file_path(self, request, response=None, info=None):
        # 提取url前面名称作为图片名。
        image_guid = request.url.split('/')[-1]
        # 接收上面meta传递过来的图片名称
        name = request.meta['name']
        # 过滤windows字符串,不经过这么一个步骤,你会发现有乱码或无法下载
        name = re.sub(r'[?\\*|“<>:/]', '', name)
        # 分文件夹存储的关键:{0}对应着name;{1}对应着image_guid
        filename = u'{0}/{1}'.format(name, image_guid)
        return filename

特别提醒:类 ImagesrenamePipeline 的参数一定是 ImagesPipeline,不是默认的 object,假如这里没有修改的话,不会执行里面的方法的。一定要注意!注意!注意!

5.编辑 settings

import os

# 设置图片存储目录
IMAGES_STORE = os.path.join(os.path.dirname(os.path.dirname(__file__)),'images')

ROBOTSTXT_OBEY = False

DOWNLOAD_DELAY = 3

ITEM_PIPELINES = {
   'ImagesRename.pipelines.ImagesrenamePipeline': 300,
}

6.运行

scrapy crawl ImgsRename

执行完成后,可以看到 ImagesRename 目录下多了 images 文件夹放了两个文件夹,而这两个文件夹下有图片。

【完】