首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >scrapy爬虫笔记(2):提取多页图片并下载至本地

scrapy爬虫笔记(2):提取多页图片并下载至本地

作者头像
冰霜
发布2022-03-15 16:52:26
发布2022-03-15 16:52:26
78900
代码可运行
举报
运行总次数:0
代码可运行

上一节使用scrapy成功提取到

https://imgbin.com/free-png/naruto/

第一页所有图片的下载链接

本节在之前的基础上,实现如下2个功能:

1、提取前10页的图片下载链接

2、下载图片至本地

一、提取指定页数图片

网站向后翻页,链接的后缀会发生如下变化

代码语言:javascript
代码运行次数:0
运行
复制
https://imgbin.com/free-png/naruto/2
https://imgbin.com/free-png/naruto/3

所以只需要构造一下传入的url即可,例如需要爬取10页图片,则 url 后缀需要从1遍历至10

1、在 settings.py 中,添加一个配置,表示最大爬取页码

代码语言:javascript
代码运行次数:0
运行
复制
MAX_PAGE = 3  # 定义爬取页数

2、编辑 images.py , 修改 start_requests()方法

代码语言:javascript
代码运行次数:0
运行
复制
def start_requests(self):
    base_url = "https://imgbin.com/free-png/naruto/"
    for page in range(1, self.settings.get("MAX_PAGE") + 1):
        url = base_url + str(page)
        yield Request(url=url, callback=self.parse)

使用 for 循环,达到 url后缀 自增的目的;

self.settings.get("MAX_PAGE") 表示读取 settings.py 配置文件中定义好的MAX_PAGE字段

在终端输入 scrapy crawl images 运行一下,得到如下结果

说明发起了10次不同的请求

二、下载图片至本地

1、在 settings.py中,添加一个配置,表示图片存储路径

代码语言:javascript
代码运行次数:0
运行
复制
IMAGES_STORE = './images'  # 图片存储至当前项目目录下的images文件夹,如果没有则会新建一个

2、编辑 pipelines.py 文件 ,定义 Image Pipeline

代码语言:javascript
代码运行次数:0
运行
复制
# 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


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

import scrapy
from scrapy.exceptions import DropItem
from scrapy.pipelines.images import ImagesPipeline
from itemadapter import ItemAdapter


class ImagePipeline(ImagesPipeline):

    def file_path(self, request, response=None, info=None):
        url = request.url
        file_name = url.split('/')[-1]  # 以图片链接最后一段xxx.jpg作为文件名
        return file_name

    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 files')
        return item

    def get_media_requests(self, item, info):
        yield scrapy.Request(item['img_src'])

官方文档中有关于上述3个方法的简介:

https://doc.scrapy.org/en/latest/topics/media-pipeline.html (1)重写 file_path()方法,返回文件保存的文件名;

(2)重写 item_completed()方法,当单个Item完成下载时(下载完成或由于某种原因失败),将调用此方法;

参数 results 就是该 Item 对应的下载结果,它是一个列表形式,列表的每一个元素是一个元组,一个元组中包含一个状态码和一个字典,形如

代码语言:javascript
代码运行次数:0
运行
复制
[(True,
  {'checksum': '2b00042f7481c7b056c4b410d28f33cf',
   'path': 'full/0a79c461a4062ac383dc4fade7bc09f1384a3910.jpg',
   'url': 'http://www.example.com/files/product1.pdf',
   'status': 'downloaded'}),
 (False,
  Failure(...))]

image_paths = [x['path'] for ok, x in results if ok], 等号右边是一个列表推导式,等价于

代码语言:javascript
代码运行次数:0
运行
复制
for ok, x in results:
    if ok:
        image_paths = [x['path']]

它的意思是如果results中某一元组结果的状态值为True,则取出该元组内字典中的path值

3、修改 settings.py,添加 ITEM_PIPELINES配置

代码语言:javascript
代码运行次数:0
运行
复制
ITEM_PIPELINES = {
    'imgbin.pipelines.ImagePipeline': 300,
}

imgbin是该scrapy项目的名称

ImagePipeline是 pipelines.py文件中定义的 Image Pipeline类名

最后在终端执行一下,就可以把前10页的图片下载至本地了

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 冰霜blog 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档