Python爬虫之Scrapy框架系列(21)——重写媒体管道类实现保存图片名字自定义及多页爬取

news2024/11/24 17:21:49

目录:

  • 重写框架自带媒体管道类部分方法实现保存图片名字的自定义:
    • 1.爬虫文件:
    • 2.items.py文件中设置特殊的字段名:
    • 3.settings.py文件中开启自建管道并设置文件存储路径:
    • 4.编写pipelines.py
    • 5.观察可发现完美实现:
    • 它的工作流是这样的:
  • 更改爬虫文件实现多页爬取:
  • 拓展:媒体管道的一些设置:

重写框架自带媒体管道类部分方法实现保存图片名字的自定义:

  1. spider文件中要拿到图片列表并yield item;
  2. item里需要定义特殊的字段名:image_urls=scrapy.Field();
  3. settings里设置IMAGES_STORE存储路径,如果路径不存在,系统会帮助我们创建;
  4. 使用默认管道则在settings.py文件中开启:scrapy.pipelines.images.ImagesPipeline: 60,
    自建管道需要继承ImagesPipeline并在settings.py中开启相应的管道;
  5. 可根据官方文档进行重写:
    get_media_requests
    item_completed

1.爬虫文件:

# -*- coding: utf-8 -*-
import scrapy

import re
from ..items import BaiduimgPipeItem
import os
class BdimgSpider(scrapy.Spider):
    name = 'bdimgpipe'
    allowed_domains = ['image.baidu.com']
    start_urls = ['https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&fm=index&pos=history&word=%E7%8C%AB%E5%92%AA']

    def parse(self, response):
        text=response.text
        image_urls=re.findall('"thumbURL":"(.*?)"',text)
        item=BaiduimgPipeItem()
        item["image_urls"]=image_urls
        yield item

2.items.py文件中设置特殊的字段名:

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

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html

import scrapy


class BaiduimgPipeItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    image_urls=scrapy.Field()

3.settings.py文件中开启自建管道并设置文件存储路径:

# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   # 'baiduimg.pipelines.BaiduimgPipeline': 300,
   'baiduimg.pipelines.BdImagePipeline': 40,
   # 'scrapy.pipelines.images.ImagesPipeline': 60,
}

# IMAGES_STORE =r'C:\my\pycharm_work\爬虫\eight_class\baiduimg\baiduimg\dir0'
IMAGES_STORE ='C:/my/pycharm_work/爬虫/eight_class_ImagesPipeline/baiduimg/baiduimg/dir3'

4.编写pipelines.py

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

# 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

from scrapy.http import Request
import os

from scrapy.pipelines.images import ImagesPipeline        # 导入要使用的媒体管道类
from .settings import IMAGES_STORE

class BdImagePipeline(ImagesPipeline):
    image_num = 0
    print("spider的媒体管道类")
    def get_media_requests(self, item, info):  # 可以用来重写
        # 将图片的URL变成请求发给引擎
        '''
        req_list=[]
        for x in item.get(self.images_urls_field, []):      #本句相当于:item["images_urls"]得到图片URL列表
            req_list.append(Request(x))
        return req_list
        '''
        return [Request(x) for x in item.get(self.images_urls_field, [])]

    def item_completed(self, results, item, info):
        images_path = [x["path"] for ok,x in results if ok]

        for image_path in images_path:  # 通过os的方法rename实现图片保存名字的自定义!第一个参数为图片原路径;第二个参数为图片自定义路径
            os.rename(IMAGES_STORE+"/"+image_path,IMAGES_STORE+"/full/"+str(self.image_num)+".jpg")      # IMAGES_STORE+"/"+image_path是图片保存的原绝对路径;第二个参数是自定义的图片保存的新绝对路径(此处也放在IMAGES_STORE路径下)
            self.image_num+=1


'''
源码中一个可重写的方法:
    def item_completed(self, results, item, info):      #此方法也可以重写
        if isinstance(item, dict) or self.images_result_field in item.fields:
            item[self.images_result_field] = [x for ok, x in results if ok]
        return item

results详解:
url-从中下载文件的网址。这是从get_media_requests() 方法返回的请求的URL 。

path- FILES_STORE文件存储的路径(相对于)

checksum- 图片内容的MD5哈希

这是该results参数的典型值:
[(True,
  {'checksum': '2b00042f7481c7b056c4b410d28f33cf',
   'path': 'full/0a79c461a4062ac383dc4fade7bc09f1384a3910.jpg',
   'url': 'http://www.example.com/files/product1.pdf'}),
]

而上面的方法item_completed()就是处理此results的,所以解读源码:
[x for ok, x in results if ok]
可知此列表推导式获取的是results中整个字典的值,然后赋给item再返回!

依此得出思路,可通过下面列表推导式获取results中图片存储的路径:
images_path = [x["path"] for ok,x in results if ok]

'''

在这里插入图片描述

5.观察可发现完美实现:

在这里插入图片描述

它的工作流是这样的:

(下面讲的是文件管道类,其实和图片管道类一个道理。因为图片管道类是继承的文件管道类,而它俩都是继承的媒体管道类~)

  1. 在爬虫中,您可以返回一个item,并将所需的url放入file_urls字段。
  2. item从爬虫返回并进入item管道。
  3. 当item到达文件管道时,file_urls字段中的url将使用标准的Scrapy调度器和下载程序(这意味着将重用调度器和下载程序中间件)计划下载, 但是具有更高的优先级,在其他页面被爬取之前处理它们。在文件下载完成(或由于某种原因失败)之前,该项在特定管道阶段保持“锁定”状态。
  4. 下载文件后,将使用另一个字段(files)填充results。这个字段将包含一个包含有关下载文件信息的dicts列表,例如下载的路径、原始的剪贴url(从file_urls字段中获得)和文件校验和。文件字段列表中的文件将保持原来file_urls字段的顺序。如果某些文件下载失败,将记录一个错误,文件将不会出现在files字段中。

更改爬虫文件实现多页爬取:

  • 注意:settings.py文件中设置个下载延迟哦!不然会有被封的危险。
# -*- coding: utf-8 -*-
import scrapy

import re
from ..items import BaiduimgPipeItem
import os
class BdimgSpider(scrapy.Spider):
    name = 'bdimgpipe'
    allowed_domains = ['image.baidu.com']
    start_urls = ['https://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&sf=1&fmq=&pv=&ic=0&nc=1&z=&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&fm=index&pos=history&word=%E7%8C%AB%E5%92%AA']
    page_url="https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E7%8C%AB%E5%92%AA&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=&copyright=&word=%E7%8C%AB%E5%92%AA&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode=&force=&pn={}&rn=30&gsm=1e&1588088573059="
    num = 0
    pagenum=1

    def parse(self, response):
        text=response.text
        image_urls=re.findall('"thumbURL":"(.*?)"',text)
        item=BaiduimgPipeItem()
        item["image_urls"]=image_urls
        yield item

        url=self.page_url.format(self.pagenum*30)
        self.pagenum+=1
        if self.pagenum == 3:			#想要多少就设置多少为中断!!!
            return
        yield scrapy.Request(url, callback=self.parse)
'''
F12观察原网页,每次加载更多图片,找到对应的URL,观察规律,发现其中pn参数的值随着页面的加载逐页增加30!!!
https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E7%8C%AB%E5%92%AA&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=&copyright=&word=%E7%8C%AB%E5%92%AA&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode=&force=&pn=30&rn=30&gsm=1e&1588088573059=
https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&queryWord=%E7%8C%AB%E5%92%AA&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&hd=&latest=&copyright=&word=%E7%8C%AB%E5%92%AA&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode=&force=&pn=60&rn=30&gsm=3c&1588088573138=
'''

效果非常nice:
在这里插入图片描述

拓展:媒体管道的一些设置:

ITEM_PIPELINES = {'scrapy.pipelines.images.ImagesPipeline': 1}  启用
FILES_STORE = '/path/to/valid/dir'		文件管道存放位置
IMAGES_STORE = '/path/to/valid/dir'		图片管道存放位置
FILES_URLS_FIELD = 'field_name_for_your_files_urls'    自定义文件url字段
FILES_RESULT_FIELD = 'field_name_for_your_processed_files'   自定义结果字段
IMAGES_URLS_FIELD = 'field_name_for_your_images_urls'  自定义图片url字段
IMAGES_RESULT_FIELD = 'field_name_for_your_processed_images'  结果字段
FILES_EXPIRES = 90    文件过期时间   默认90天
IMAGES_EXPIRES = 90    图片过期时间   默认90天
IMAGES_THUMBS = {'small': (50, 50), 'big':(270, 270)}  缩略图尺寸                              # !!!直接在settings.py中写入此设置,再运行框架就会生成缩略图!!!十分方便,常用!!!
IMAGES_MIN_HEIGHT = 110   过滤最小高度
IMAGES_MIN_WIDTH = 110   过滤最小宽度
MEDIA_ALLOW_REDIRECTS = True    是否重定向

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/630494.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JetBrains 激活方式的区别

文章目录 简介激活方式 简介 JetBrains 是一家全球知名的软件开发工具公司。 JetBrains 成立于 2000 年,总部位于捷克共和国的布拉格。该公司致力于为开发者提供高效、智能和创新的软件开发工具,以提升开发人员的生产力和开发体验。 JetBrains 的主要…

Redis的主从复制、哨兵机制、集群

一、主从复制 1、定义 主:master以写为主当master数据变化的时候从:slave以读为主自动将新的数据异步同步到其他slave数据库 2、作用 读写分离、容灾恢复、数据备份、水平扩容支撑高并发。 3、使用方式——配从不配主 权限配置:master如…

【图书推荐 | 13】后端系列

【赠书活动第十二期 】 图书推荐 本期书籍:后端系列 图书列表 本期图书列表: Spring Cloud 微服务快速上手项目驱动零起点学JavaNode.js 从基础到项目实战Diango Web 开发实例精解Flask Web 全栈开发实战精通Hadoopsmysql 数据库基础与实战应用Neo4j 图谱…

指针--用指针变量作函数参数的实例(按值调用与模拟按引用调用)、函数指针及其应用

一、用指针变量作函数参数的实例 思考题&#xff1a; 例题&#xff1a;从键盘输入某班学生某门课成绩&#xff08;每班人数最多不超过40人&#xff0c;具体人数由键盘输入&#xff09;&#xff0c;是分析下列程序是否能实现计算并输出最高分以及相应学号。 #include <stdi…

群晖 NAS 外网访问设置 - 腾讯 DNSPod

目录 ​编辑 一、使用DNSPod&#xff0c;实现DDNS&#xff08;动态域名&#xff09; 二、公共概念厘清 三、腾讯DNSPod上详细设置步骤 1. 打开DNSPod.cn网站并登录 2. 登录成功后&#xff0c;选择【我的域名】-> 【添加域名】 3. 添加群晖NAS需要二级域名&#xff08…

Visual Studio封装静态链接库至新静态库,供程序调用

熟悉Windows开发的人都肯定了解静态链接库和动态链接库。 最近遇到一个问题&#xff1a; A静态库是使用VS编译&#xff0c;因为C版本的问题&#xff0c;并不能直接在Qt中被调用&#xff0c;因为会报头文件某处错误。 因为A库很大&#xff0c;同时又不想修改太多A库源文件&#…

开源社章程(2023版)

第 1 条 开源社是由志愿贡献于开源事业的个人志愿者&#xff0c;依 “贡献、共识、共治” 原则所组成的开源社区。第 2 条 开源社的英文名称为“KAIYUANSHE”&#xff0c;官方网站地址为 https://kaiyuanshe.cn/第 3 条 开源社的愿景为&#xff1a;立足中国、贡献全球&#xff…

English Learning - L3 作业打卡 Lesson5 Day36 2023.6.9 周五

English Learning - L3 作业打卡 Lesson5 Day36 2023.6.9 周五 引言&#x1f349;句1: So next time you are on a train, look around and see what other people are reading, but dont jump to any conclusions.成分划分弱读连读爆破语调 &#x1f349;句2: You will probab…

MIT 6.S081 Lab One

MIT 6.S081 Lab One 引言sleep(难度&#xff1a;Easy)解析Lab代码实现 pingpong&#xff08;难度&#xff1a;Easy&#xff09;Lab代码实习 小结 引言 本文为 MIT 6.S081 2020 操作系统 实验一解析。 MIT 6.S081课程前置基础参考: 基于RISC-V搭建操作系统系列 sleep(难度&…

English Learning - L3 作业打卡 Lesson5 Day34 2023.6.7 周三

English Learning - L3 作业打卡 Lesson5 Day34 2023.6.7 周三 引言&#x1f349;句1: The woman reading the romantic novel could be a lawyer.成分划分弱读连读爆破语调 &#x1f349;句2: She just wants a light read to take her mind off work.成分划分弱读连读爆破语调…

STM32读取MQ2烟雾浓度数据判断烟雾是否超标

【1】MQ2传感器是什么&#xff1f; MQ2传感器是一种可探测多种气体的传感器&#xff0c;常用于监测烟雾、液化气、丙酮、乙醇、甲醛、天然气等有害气体。MQ2传感器基于半导体敏感元件&#xff0c;通过检测气体中有害物质的浓度变化来实现气体检测。 MQ2传感器具有以下特点&a…

Python的self作用,以及__init__,__new__

本章来探讨一下Python类的self作用&#xff0c;以及__init__,__new__。 为什么是探讨&#xff0c;不是学习&#xff0c;因为菜&#x1f40e;&#xff1b; 先看个例子&#xff1a; class Example:def animal(self):self.dog "大黄"def Dog(self):print(self.dog)if _…

【前端 - CSS】第 10 课 - CSS 引入方式

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01; 时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、缘起 2、CSS 引入方式 2.1、内部样式表 2.2、外部样式表 2.3、行内样式 3、总结 1、缘起 要想在 HTML 代码中写入 CSS 代…

English Learning - L3 作业打卡 Lesson5 Day33 2023.6.6 周二

English Learning - L3 作业打卡 Lesson5 Day33 2023.6.6 周二 引言&#x1f349;句1: And theres a student reading an English textbook.成分划分弱读连读语调 &#x1f349;句2: What do their choices say about them?成分划分连读爆破语调 &#x1f349;句3: Do you jud…

nodejs+vue+Express论坛网站34t91

本论坛网站有管理员&#xff0c;用户&#xff0c;普通管理员。管理员功能有个人中心&#xff0c;用户管理&#xff0c;普通管理员管理&#xff0c;论坛类别管理&#xff0c;交流论坛管理&#xff0c;系统管理等。用户功能有个人中心&#xff0c;交流论坛管理&#xff0c;我的收…

华为OD机试真题 JavaScript 实现【水仙花数】【2022Q4 100分】

一、题目描述 所谓水仙花数&#xff0c;是指一个n位的正整数&#xff0c;其各位数字的n次方和等于该数本身。 例如153是水仙花数&#xff0c;153是一个3位数&#xff0c;并且153 1^3 5^3 3^3。 二、输入描述 第一行输入一个整数n&#xff0c;表示一个n位的正整数。n在3到…

单容水箱建模(自衡单容水箱+无自衡单容水箱)

自衡单容水箱Simulink建模和PLC源代码请参看下面文章链接: 单容双容水箱建模(simulink仿真+PLC代码)_RXXW_Dor的博客-CSDN博客PLC通过伯努利方程近似计算水箱流量详细内容请参看下面的文章博客PLC通过伯努利方程近似计算水箱流量(FC)_怎么用伯努利方程求某水位流量_RXXW_Dor的…

基础汇编语言编程

目录 什么是汇编语言&#xff1f; 工程搭建 新建工程 环境设置 测试是否成功 正式学习汇编语言 数据处理指令 填充&#xff0c;加&#xff0c;减&#xff0c;乘 思考&#xff1a;我们可以看到R0寄存器可以存放8位十六进制数&#xff0c;那么0x12345678能不能用mov存入&am…

java SSM 摄影作品网站myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM 摄影作品网站系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代 码和数据库&#xff0c;系统主要采…

会用Python做副业的人,有多豪横!

前两天一个朋友找到我吐槽&#xff0c;说工资一发交完房租水电&#xff0c;啥也不剩&#xff0c;搞不懂朋友圈里那些天天吃喝玩乐的同龄人钱都是哪来的&#xff1f; 确实如此&#xff0c;刚毕业的大学生工资起薪都很低&#xff0c;在高消费、高租金的城市&#xff0c;别说存钱…