Scrapy从入门到精通(5)--下载文件和图片

Scrapy从入门到精通系列前四篇已经讲了从网页中获取信息的方法,除此之外,爬虫也可以从网页中下载图片、视频、word、pdf、压缩包等

FilesPipeline和ImagePipeline

Scarpy框架内部提供了这两个Item Pipeline专门用来下载文件和图片
可以将它们视为特殊下载器,给他们url,就会自动下载到本地,并将下载结果存入item的另一个特殊字段,以便用户在导出文件中查阅

FilesPipeline

例子

<html>
    <body>
        <a href='/book/sg.pdf'>下载《三国》a>
        <a href='/book/sg.pdf'>下载《水浒》a>
        <a href='/book/sg.pdf'>下载《红楼》a>
        <a href='/book/sg.pdf'>下载《西游》a>

    body>
html>
  1. 在配置文件settings.py中启用FilesPipeline,通常将其置于首位
ITEM_PIPELINES = {'scrapy.pipelines.files.FilesPipeline':1}
  1. 在配置文件settings.py中指定下载目录
FILES_STORE = '/home/liushuo/Download/scrapy'

3.在Spider解析一个包含文件下载链接的页面, 将所有url地址收集到一个列表,赋值给item的file_urls字段(item[‘file_urls’]).

class DownloadBookSpider(scrapy.Spider):

def parse(response):
item = {}
item['file_urls'] = []
for url in response.xpath('//a/@href').extract():
    download_url = response.urljoin(url)
    #将url填入下载列表
    item['file_urls'].append(download_url)
yield item

当FilePipeline下载完item[‘file_urls’]中所有文件中,各文件的下载结果信息收集到另一个列表,赋给item的files字段(item[‘files’]),下载结果信息包含以下

  • path 文件下载到本地路径(相当于FILES_STORE的相对路径)
  • Checksum 文件的校验和
  • URL 文件和URL地址

    ImagesPipeline使用说明

    图片也是文件,所以下载图片本质上也是下载文件
    ImagesPipeline和FilesPiplines使用类似,只是在使用item字段和配置选项上略有差别

         - ImagesPipeline                             FilePipeline
    

    scrapy.pipelines.ImagesPipline 2 scrapy.pipelines.files.FilesPipline
    file_urls,files 2 image_urls,images
    FILES_STORE 2IMAGES_STORE

ImagesPipeline在FilesPipleline的基础上针对图片增加一些特有功能:

  • 为图片生成缩略图
 开启该功能,在配置文件中设置IMAGES_THUMBS,他是一个字典,每一项的值是缩略图的尺寸
`IMAGES_THUMBS = {
     - 'small':(50,50),
     - 'big':(270,270),
     - }`
  • 过滤掉尺寸过小的图片
设置IMGAES_MIN_WIDTH和IMAGES_MIN_HEIGHT,
IMGAES_MIN_WIDTH = 110
IMAGES_MIN_HEIGHT = 110

项目实战:下载360图片

http://images.so.com

项目需求
爬去360图片艺术类
页面分析
滚轮向下滑动,自动加载更多的图片,用的是jQuery发送的请求,相应结果为一个json串。
Scrapy从入门到精通(5)--下载文件和图片_第1张图片
复制图中的jQuery发送请求的url,使用scrapy shell 进行访问,查看相应结果的json:

$scrapy shell 'http://images.so.com/zj?ch=art&sn=90&listtype=new&temp=1'

import json
res = json.loads(response.body.decode('utf8'))
res

Scrapy从入门到精通(5)--下载文件和图片_第2张图片

如图所示,相应结果(json)中的list字段是一个图片信息列表,count:列表中图片信息的数量
qhimg_url:图片的下载链接

连续滑动,获取多次jQuery请求

第一次加载:http://images.so.com/zj?ch=art&sn=30&listtype=new&temp=1
第二次加载:http://images.so.com/zj?ch=art&sn=60&listtype=new&temp=1
第三次加载:http://images.so.com/zj?ch=art&sn=90&listtype=new&temp=1

ch参数:分类标签
sn参数:从第几张图片开始加载,也是第一张图片得服务器中的编号

编码实现spider

  • 创建Scrapy项目,并使用scrapy genspider命令创建spider
  • 在配置文件中启用ImagesPipeline,指定下载目录
  • 实现ImageSpider

    创建Scrapy项目,并使用scrapy genspider命令创建spider

Scrapy startproject so_image
cd so_image
scrapy genspider images images.so.com

在配置文件中启用ImagesPipeline,指定下载目录

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

实现ImagesSpider

# -*- coding: utf-8 -*-
import scrapy
from scrapy import Request
import json


class ImagesSpider(scrapy.Spider):
    name = 'images'
  #  allowed_domains = ['images.so.com']

    BASE_URL = 'http://images.so.com/zj?ch=art&sn=%s&listtype=new&temp=1'
    start_index = 0

    # 限制最大下载数量
    MAX_DOWNLOAD_NUM = 1000
    start_urls = [BASE_URL % 0]




    def parse(self, response):
        #使用json模块解析响应结果
        infos = json.loads(response.body.decode('utf-8'))
        #提取所有下载url到一个列表,赋给item的‘image_urls’字段
        yield {'images_urls':[info['qhimg_url']for info in infos['list']]}

    #如果count字段大于0,并且下载数量不足MAX_DOWNLOAD_NUM继续获取下一页
        self.start_index += infos['count']
        if infos['count'] > 0 and self.start_index < self.MAX_DOWNLOAD_NUM:
            yield Request(self.BASE_URL%self.start_index)

运行spider

scrapy crawl images

转载于:https://www.cnblogs.com/oifengo/p/9385945.html

你可能感兴趣的:(Scrapy从入门到精通(5)--下载文件和图片)