Scrapy下载图片

47 阅读3分钟

scrapy为下载item中包含的⽂件提供了⼀个可重⽤的item pipelines,这些pipeline有些共同的⽅法和结构,⼀般来说你会使⽤Files Pipline或者ImagesPipeline

创建项目

scrapy startproject cyj

创建爬虫文件

scrapy genspider cos www.cyjdm.com

图片.png

不使用Scrapy下载中间件的方式

import scrapy


class CosSpider(scrapy.Spider):
    name = "cos"
    allowed_domains = ["www.cyjdm.com"]
    start_urls = ["https://www.cyjdm.com/cosplay/page_1.html"]

    def parse(self, response):
        lis = response.xpath("//div[@class='kz-PostList KZ-Ui01']/ul/li")
        for li in lis:
            item = {}
            # 获取图片名字
            img_name = li.xpath(".//img/@alt").extract_first()
            item['img_name'] = img_name

            # 获取图片链接
            img_url = li.xpath(".//img/@data-original").extract_first()
            item['img_url'] = img_url

            yield item

保存时使用urllib库 pipelins.py代码:

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
import os.path

# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
from urllib import request


class CyjPipeline:
    def process_item(self, item, spider):
        # print(item)
        url = item['img_url']
        img_name = item['img_name']
        # 保存路径
        file_path = os.path.join(os.path.dirname(__file__), 'imges')
        if not os.path.exists(file_path):
            os.makedirs(file_path)

        request.urlretrieve(url, file_path + '\\' + img_name + '.jpg')
        print(img_name)
        return item

创建一个start.py文件用来启动爬虫

from scrapy import cmdline  
  
if __name__ == '__main__':  
cmdline.execute(['scrapy', 'crawl', 'cos'])

运行结果:

图片.png

使用Scrapy框架的内置下载方法

为什么要选择使⽤scrapy内置的下载⽂件的⽅法

  1. 避免重新下载最近已经下载过的数据

  2. 可以⽅便的指定⽂件存储的路径

  3. 可以将下载的图⽚转换成通⽤的格式。如:png,jpg

  4. 可以⽅便的⽣成缩略图

  5. 可以⽅便的检测图⽚的宽和⾼,确保他们满⾜最⼩限制

  6. 异步下载,效率⾮常⾼

下载图⽚的 Images Pipeline

使⽤images pipeline下载⽂件步骤:

  • 定义好⼀个Item,然后在这个item中定义两个属性,分别为image_urls以及images。image_urls是⽤来存储需要下载的⽂件的url链接,需要给⼀个列表

  • 当⽂件下载完成后,会把⽂件下载的相关信息存储到item的images属性中。如下载路径、下载的url和图⽚校验码等在配置⽂件settings.py中配置IMAGES_STORE,这个配置⽤来设置⽂件下载路径

  • 启动pipeline:在ITEM_PIPELINES中设置

    scrapy.pipelines.images.ImagesPipeline:1

定义item中的两个属性

import scrapy  
class Cyj2Item(scrapy.Item):  
image_urls = scrapy.Field()  
images = scrapy.Field()

爬虫部分代码编写

import scrapy
from cyj2.items import Cyj2Item

class CosSpider(scrapy.Spider):
    name = "cos"
    allowed_domains = ["www.cyjdm.com"]
    start_urls = ["https://www.cyjdm.com/cosplay/page_1.html"]

    def parse(self, response):
        lis = response.xpath("//div[@class='kz-PostList KZ-Ui01']/ul/li")
        for li in lis:
            # item = {}
            item = Cyj2Item()
            # 获取图片名字
            # img_name = li.xpath(".//img/@alt").extract_first()
            # item['imge_name'] = img_name.replace(':', '')

            # 获取图片链接
            img_url = li.xpath(".//img/@data-original").extract_first()
            item['image_urls'] = img_url

            yield item

在settings.py的配置

import os  
IMAGES_STORE = os.path.join(os.path.dirname(os.path.dirname(__file__)),'images')

启动pipeline:在ITEM_PIPELINES中设置

ITEM_PIPELINES = {  
    "cyj2.pipelines.Cyj2Pipeline": 300,  
    'scrapy.pipelines.images.ImagesPipeline': 1  
}

运行结果:

图片.png

下载⽂件的 Files Pipeline

使⽤Files Pipeline下载⽂件,按照以下步骤完成:

  • 定义好⼀个Item,然后在这个item中定义两个属性,分别为file_urls以及files。files_urls是⽤来存储需要下载的⽂件的url链接,需要给⼀个列表

  • 当⽂件下载完成后,会把⽂件下载的相关信息存储到item的files属性中。如下载路径、下载的url和⽂件校验码等

  • 在配置⽂件settings.py中配置FILES_STORE,这个配置⽤来设置⽂件下载路径

  • 启动pipeline:在ITEM_PIPELINES中设置

    scrapy.piplines.files.FilesPipeline:1