【爬虫】-014-Scrapy-内置图片管道实例

本次项目以pexels.com图片网站为例,介绍Scrapy内置图片下载管道的使用

1.分析目标网站的目录结构

图片详情页的链接结构和特点,多尝试不同入口寻找图片链接的特点;分析网站的目录层级结构特点,通过点击不同入口看到不同菜单、不同类目下的菜单层级结构特点。

  • 以pexels.com为例,这个网站中的图片可以免费下载,并以商业或个人使用,是个不错的图片资源网站。因为这次爬取图片,所以不对其中的视频内容链接进行分析。

  • 点击不同的图片,发现图片详情页链接类似这样:https://www.pexels.com/photo/stretching-white-cat-979247/

    图片详情页

  • 最终图片页面的链接类似这样:https://images.pexels.com/photos/979247/pexels-photo-979247.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260

    图片页面

  • 推测图片详情页的链接由:域名(https://www.pexels.com ),图片目录(photo),图片名称构成(stretching-white-cat-979247)

  • 图片链接的构成由:域名(https://www.pexels.com ),图片目录(photo),图片ID(979247)和图片名称构成(stretching-white-cat-979247),问号后面的是图片加载时候的参数。

  • 虽然也有不同的目录,但是最终图片的出口都是photo➕图片名的组合


    【爬虫】-014-Scrapy-内置图片管道实例_第1张图片
    其他目录

2.接下来创建爬虫项目文件

  • 创建爬虫项目:scrapy startproject images
  • 使用内置的crawl模板创建爬虫: scrapy genspider -t crawl pexels pexels.com

3.用pycharm打开项目文件

  • 简单测试一些爬虫爬取流程, 打开爬虫目录中爬虫文件,编辑rules中的提取规则,获取图片详情页所有图片的url链接
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule


class PexelsSpider(CrawlSpider):
    name = 'pexels'
    allowed_domains = ['pexels.com']
    start_urls = ['http://pexels.com/']

    rules = (
        # 设置爬取规则
        Rule(LinkExtractor(allow=r'https://www.pexels.com/photo/.*'), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        item = {}
        #item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()
        #item['name'] = response.xpath('//div[@id="name"]').get()
        
        # 获取图片详情页中所有图片的URL,包括图片作者头像等
        item['url'] = response.xpath('.//img[contains(@src, "http")]/@src').extract()
        print(item)
        # return item

image.png
  • OK爬虫正常,现在启动框架内置的管道文件进行图片下载

--首先,在settings文件中,找到item_pipeline进行如下配置

ITEM_PIPELINES = {
    'scrapy.pipelines.images.ImagesPipeline': 1,
   # 'images.pipelines.ImagesPipeline': 300,
}

配置表明,设置启动内置到图片管道,参数1表示优先级最高,优先使用该管道配置。
-- 然后,指定图片存储路径


image.png

-- 配置items.py文件

import scrapy

class ImagesItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    # 设置图片url字段
    image_urls = scrapy.Field()
    # 图片请求的网址,检验码信息,下载的文件路径
    images = scrapy.Field()
    pass

-- 修改爬虫文件代码如下

# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from ..items import ImagesItem

class PexelsSpider(CrawlSpider):
    name = 'pexels'
    allowed_domains = ['pexels.com']
    start_urls = ['http://pexels.com/']

    rules = (
        # 设置爬取规则
        Rule(LinkExtractor(allow=r'https://www.pexels.com/photo/.*'), callback='parse_item', follow=True),
    )

    def parse_item(self, response):
        item = ImagesItem()
        #item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()
        #item['name'] = response.xpath('//div[@id="name"]').get()

        # 获取图片详情页中所有图片的URL,包括图片作者头像等
        item['image_urls'] = response.xpath('.//img[contains(@src, "http")]/@src').extract()
        # print(item)
        # 返回到图片管道中
        return item

-- 跑一下程序,可以看到如图所示,表示图片URL和下载对应到内容全部成功。


爬虫运行日志
  • 如果需要下载高清图片,则需要对获取对图片URL进行处理,截图中可以看到,下载对URL图片都是带有参数对,所以去掉参数就可以获取到原始高清图片;思路就是用两个管道文件,一个用于清理数据,另一个用来下载图片。

-- 修改settings.py中管道文件配置项

ITEM_PIPELINES = {
    'scrapy.pipelines.images.ImagesPipeline': 2,
    'images.pipelines.ImagesPipeline': 1,
}

-- 修改pipelines.py文件ImagesPipeline类的逻辑,获取高清图片url


class ImagesPipeline(object):
    def process_item(self, item, spider):
        # 设置一个临时列表变量,存储获取的图片链接
        tmp = item['image_urls']
        # 清空原有的图片链接
        item['image_urls'] = []

        # 查找图片中带参数的url,如果有问号,则去掉问号后面的参数,然后将URL重新放回管道中
        for url in tmp:
            if '?' in url:
                item['image_urls'].append(url.split('?')[0])
            else:
                item['image_urls'].append(url)
        # 将爬虫获取的函数经过当前管道进行处理封装,然后返回进入下一个管道
        return item
  • 还可以启用图片管道的参数配置选项,对下载图片的宽高和比例进行限制筛选。
    -- 进入settings.py文件设置图片最小高度和宽度参数
# 设置图片最小高度和宽度
IMAGES_MIN_HEIGHT = 1000
IMAGES_MIN_WIDTH = 1200
# 设置图片过期,本次爬虫不会在过期有效期内对图片进行二次下载,单位是天
IMAGES_EXPIRES = 90
# 下载图片的同时下载缩略图,尺寸可调整
IMAGES_THUMBS = {
    'small': (50, 50),
    'big': (800, 800),
}

你可能感兴趣的:(【爬虫】-014-Scrapy-内置图片管道实例)