scrapy爬取图片

文章目录

  • ImagesPipeline
  • 使用步骤:
    • 1. 数据解析: 获取图片的地址 & 2. 将存储图片地址的item提交到指定的管道类(`hotgirls.py`)
    • 3. 在管道文件中自制一个基于ImagesPipeLine的一个管道类
      • !!天大的坑 !!
    • 4. 在配置文件settings.py中:
    • item()类
  • 完整代码
    • hotgilrs.py 爬虫文件
    • items.py
    • pipelines.py

使用scrapy爬取图片,采用管道方法进行下载。

  • 这里采用继承ImagesPipeline类的方法来重写get_media_requests,file_path, item_completed。

ImagesPipeline

只需要img的src属性值进行解析,提交给该管道,该管道就会对图片的src进行请求发送获取图片的二进制数据,且保存到本地。

使用步骤:

  1. 数据解析: 获取图片的地址
  2. 将存储图片地址的item提交到指定的管道类
  3. 在管道文件中自制一个基于ImagesPipeLine的一个管道类
    • get_media_requests
    • file_path
    • item_completed
  4. 在配置文件settings.py中:
    • 指定图片的存储路径: IMAGES_STORE
    • 指定开启的管道:自定制的管道类。

本次解析的网站地址:https://www.tuiimg.com/meinv/在这里插入图片描述
谁不爱呢哈哈哈

原本思路:

  1. 每个图片对应一个图集的url。将这些图集详情页url保存下来,对这些详情页url进行解析。
  2. 将这些详情页url中的图片爬取下来

后来发现这个思路不太可行。因为在详情页中还需要点击展开全图,这需要用到selenium的操作,加上scrapy我实现了一下失败了,所以后面换别的方法。

在这里插入图片描述
发现在初始界面的图片src为https://i.tuiimg.net/007/3007/c.jpg
然后点进去他的详情页,发现它每张照片的url为:
在这里插入图片描述
所以我只需要将预览图的c.jpg换成123456就可以得到所有的图片src

1. 数据解析: 获取图片的地址 & 2. 将存储图片地址的item提交到指定的管道类(hotgirls.py

parse() 用于获取所有不同图集的图片src模板,即将c.jpg去掉。
parse_length() 用于获取每个图集的图片张数,并解析每一张图片,将其yield给管道并下载。

from time import sleepimport scrapy
from hotgilrsPro.items import HotgilrsproItemclass HotgirlsSpider(scrapy.Spider):name = "hotgirls"# allowed_domains = ["www.xxx.com"]start_urls = ["https://www.tuiimg.com/meinv/"]name_src_list = []idx = 0def parse_length(self, response):item = response.meta['item']#  print("当前在parse_length中解析的页面", response.url)length = response.xpath('.//div[@id="page"]/span[2]/i//text()').extract_first()length = int(length.split('/')[-1][:-1])    # 从str:展开全图(1/75)转到int: 75item['length'] = lengthprint("当前的idx", self.idx)# print("当前长度为:", length)for i in range(1, length+1):#print("保存在字典中的改写的src为",src, "字典模板为", self.dic['img_template'])url = self.name_src_list[self.idx]['img_template'] + f"/{i}.jpg"item['src'] = url# print("在parse_length中生成的url:", url)yield item	# 将带有图片src的item传给管道,对应 2. 将存储图片地址的item提交到指定的管道类self.idx += 1def parse(self, response):# scrapy框架的内容li_list = response.xpath('/html/body/div[3]/ul/li') # /html/body/div[3]/ulitem = HotgilrsproItem()item['page_url'] = []for li in li_list:name = li.xpath('.//a[2]/text()').extract_first()img_template = li.xpath('.//a[1]/img/@src').extract_first()img_template = img_template[:img_template.rfind('/')]   # 得到前面的模板img_template = ''.join(img_template)print("当前的name:", name)print("当前的模板:", img_template)item['img_template'] = img_templatedic = {}dic['name'] = nameitem['name'] = namedic['img_srcs'] = {}dic['img_template'] = img_templateself.name_src_list.append(dic)page_src = li.xpath('./a[1]/@href').extract_first()item['page_url'].append(page_src)yield scrapy.Request(url=page_src, callback=self.parse_length, meta={'item': item})  # 这一步是异步的,在这儿等请求响应并接着往下执行。print(self.name_src_list)

3. 在管道文件中自制一个基于ImagesPipeLine的一个管道类

!!天大的坑 !!

    return 'images/' + str(self.imgName) + ".jpg"	

这里写图片的路径的时候,前面必须再加上一个目录名,否则不会保存到本地,!!!!

# 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 scrapy
# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
from scrapy.pipelines.images import ImagesPipeline
# from hotgilrsPro.spiders.hotgirls import name_src_list# 写这里别忘了修改settings。
# class HotgilrsproPipeline:
#     def process_item(self, item, spider):
#         return itemclass imgsPileLine(ImagesPipeline):imgName = 1# 可以根据图片地址进行图片数据的请求def get_media_requests(self, item, info):#  print("当前在pipelines中请求到图片地址:", item['src'])yield scrapy.Request(item['src'])# 指定图片的存储路径# 这里本来想将图集名称也爬取下来,放到多个文件夹下,但是能力不够没能实现。只能按照张数123一张一张胡乱存。def file_path(self, request, response=None, info=None):print("当前图片", request.url, "的存储路径", self.imgName)self.imgName += 1return 'images/' + str(self.imgName) + ".jpg"	def item_completed(self, results, item, info):return item     # 返回给下一个即将被执行的管理类

4. 在配置文件settings.py中:

#指定图片存储的目录
IMAGES_STORE = './imgs_hotgirls'# 开启指定管道
ITEM_PIPELINES = {# "hotgilrsPro.pipelines.HotgilrsproPipeline": 300,"hotgilrsPro.pipelines.imgsPileLine": 250,}

item()类

class HotgilrsproItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()# 在item中定义相关的属性length = scrapy.Field()name = scrapy.Field()src = scrapy.Field()page_url = scrapy.Field()img_template = scrapy.Field()

完整代码

hotgilrs.py 爬虫文件

from time import sleepimport scrapy
from hotgilrsPro.items import HotgilrsproItemclass HotgirlsSpider(scrapy.Spider):name = "hotgirls"# allowed_domains = ["www.xxx.com"]start_urls = ["https://www.tuiimg.com/meinv/"]name_src_list = []idx = 0def parse_length(self, response):item = response.meta['item']#  print("当前在parse_length中解析的页面", response.url)length = response.xpath('.//div[@id="page"]/span[2]/i//text()').extract_first()length = int(length.split('/')[-1][:-1])    # 从str:展开全图(1/75)转到int: 75item['length'] = lengthprint("当前的idx", self.idx)# print("当前长度为:", length)for i in range(1, length+1):#print("保存在字典中的改写的src为",src, "字典模板为", self.dic['img_template'])url = self.name_src_list[self.idx]['img_template'] + f"/{i}.jpg"item['src'] = url# print("在parse_length中生成的url:", url)yield itemself.idx += 1def parse(self, response):# scrapy框架的内容li_list = response.xpath('/html/body/div[3]/ul/li') # /html/body/div[3]/ulitem = HotgilrsproItem()item['page_url'] = []for li in li_list:name = li.xpath('.//a[2]/text()').extract_first()img_template = li.xpath('.//a[1]/img/@src').extract_first()img_template = img_template[:img_template.rfind('/')]   # 得到前面的模板img_template = ''.join(img_template)print("当前的name:", name)print("当前的模板:", img_template)item['img_template'] = img_templatedic = {}dic['name'] = nameitem['name'] = namedic['img_srcs'] = {}dic['img_template'] = img_templateself.name_src_list.append(dic)page_src = li.xpath('./a[1]/@href').extract_first()item['page_url'].append(page_src)yield scrapy.Request(url=page_src, callback=self.parse_length, meta={'item': item})  # 这一步是异步的,在这儿等请求响应并接着往下执行。print(self.name_src_list)

items.py

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.htmlimport scrapyclass HotgilrsproItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()length = scrapy.Field()name = scrapy.Field()src = scrapy.Field()page_url = scrapy.Field()img_template = scrapy.Field()

pipelines.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 scrapy
# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
from scrapy.pipelines.images import ImagesPipeline
# from hotgilrsPro.spiders.hotgirls import name_src_list# 写这里别忘了修改settings。
# class HotgilrsproPipeline:
#     def process_item(self, item, spider):
#         return itemclass imgsPileLine(ImagesPipeline):imgName = 1# 可以根据图片地址进行图片数据的请求def get_media_requests(self, item, info):#  print("当前在pipelines中请求到图片地址:", item['src'])yield scrapy.Request(item['src'])# 指定图片的存储路径def file_path(self, request, response=None, info=None):print("当前图片", request.url, "的存储路径", self.imgName)self.imgName += 1return 'images/' + str(self.imgName) + ".jpg"def item_completed(self, results, item, info):return item     # 返回给下一个即将被执行的管理类

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

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

相关文章

ChatGPT Prompting开发实战(十二)

一、如何开发prompts实现个性化的对话方式 通过设置“system”和“user”等roles,可以实现个性化的对话方式,并且可以结合参数“temperature”的设定来差异化LLM的输出内容。在此基础上,通过构建一个餐馆订餐对话机器人来具体演示对话过程。…

git你学“废”了吗?——git撤销操作指令详解

git你学“废”了吗?——git撤销操作指令详解😎 前言🙌撤销的本质撤销修改情况一:撤销工作区的修改方式一:方式二:演示截图: 撤销修改情况二:撤销暂存区和工作区的修改操作截图&#…

为什么字节大量用GO而不是Java?

见字如面,我是军哥。 我看很多程序员对字节编程语言选型很好奇,为此我还特地问了在字节的两位4-1的技术大佬朋友,然后加上自己的思考,总结了一下就以下 2 个原因: 1、 选型上没有历史包袱 字节的早期的程序员大多来自于…

CISSP学习笔记:PKI和密码学应用

第七章 PKI和密码学应用 7.1 非对称密码学 对称密码系统具有共享的秘钥系统,从而产生了安全秘钥分发的问题非对称密码学使用公钥和私钥对,无需支出复杂密码分发系统 7.1.1 公钥与私钥 7.1.2 RSA(兼具加密和数字签名) RSA算法…

[论文笔记]UNILM

引言 今天带来论文Unified Language Model Pre-training for Natural Language Understanding and Generation的笔记,论文标题是 统一预训练语言模型用于自然语言理解和生成。 本篇工作提出了一个新的统一预训练语言模型(Unifield pre-trained Language Model,UniLM),可以同…

Linux基本操作符(2)

W...Y的主页 😊 代码仓库分享 💕 关于Linux的操作符,在上篇博客中我们已经讲述了一些,都是Linux最基本的操作符。今天我们继续了解一些关于对文件及目录增删查改的操作符,话不多说我们直接上内容。 目录 rm指令的回…

Git/GitHub/Idea的搭配使用

目录 1. Git 下载安装1.1. 下载安装1.2. 配置 GitHub 秘钥 2. Idea 配置 Git3. Idea 配置 GitHub3.1. 获取 GitHub Token3.2. Idea 根据 Token 登录 GitHub3.3. Idea 提交代码到远程仓库3.3.1. 配置本地仓库3.3.2. GitHub 创建远程仓库1. 创建单层目录2. 创建多层目录3. 删除目…

大数据-玩转数据-Flink Sql 窗口

一、说明 时间语义,要配合窗口操作才能发挥作用。最主要的用途,当然就是开窗口然后根据时间段做计算了。Table API和SQL中,主要有两种窗口:分组窗口(Group Windows)和 含Over字句窗口(Over Win…

卤制品配送经营商城小程序的用处是什么

卤制品也是食品领域重要的分支,尤其对年轻人来说,只要干净卫生好吃价格合理,那复购率宣传性自是不用说,而随着互联网发展,传统线下门店也须要通过线上破解难题或进一步扩大生意。 而商城小程序无疑是商家通过线上私域…

字符串函数与内存函数讲解

文章目录 前言一、字符串函数1.求字符串长度strlen 2.长度不受限制的字符串函数(1)strcpy(2)strcat(3)strcmp 3.长度受限制的字符串函数(1)strncpy(2)strncat(3)strncmp 4.字符串查找(1)strstr(2)strtok 5.错误信息报告(1)strerror(2)perror 二、内存函数1.memcpy2.memmove3.me…

Neural Networks for Fingerprint Recognition

Neural Computation ( IF 3.278 ) 摘要: 在采集指纹图像数据库后,设计了一种用于指纹识别的神经网络算法。当给出一对指纹图像时,算法输出两个图像来自同一手指的概率估计值。在一个实验中,神经网络使用几百对图像进行训练&…

第 365 场 LeetCode 周赛题解

A 有序三元组中的最大值 I 参考 B B B 题做法… class Solution { public:using ll long long;long long maximumTripletValue(vector<int> &nums) {int n nums.size();vector<int> suf(n);partial_sum(nums.rbegin(), nums.rend(), suf.rbegin(), [](int x…

golang工程——protobuf使用及原理

相关文档 源码&#xff1a;https://github.com/grpc/grpc-go 官方文档&#xff1a;https://www.grpc.io/docs/what-is-grpc/introduction/ protobuf编译器源码&#xff1a;https://github.com/protocolbuffers/protobuf proto3文档&#xff1a;https://protobuf.dev/programmin…

加入PreAuthorize注解鉴权之后NullPointerException报错

记录一次很坑的bug&#xff0c;加入PreAuthorize注解鉴权之后NullPointerException报错&#xff0c;按理来说没有权限应该403报错&#xff0c;但是这个是500报错&#xff0c;原因是因为controller层的service注入失败&#xff0c;然而我去掉注解后service注入成功&#xff0c;并…

使用VSCODE 调试ros2具体设置

vscode 调试 ROS2 张得帅&#xff01; 于 2023-09-09 15:39:39 发布 456 收藏 1 文章标签&#xff1a; vscode ros2 版权 1、在下列目录同层级找到.vscode文件夹 . ├── build ├── install ├── log └── src 2、 安装ros插件 3、创建tasks.json文件&#xff0c;添…

二十七、[进阶]MySQL默认存储引擎InnoDB的简单介绍

1、MySQL体系结构 MySQL大致可以分为连接层、服务层、引擎层、存储层四个层&#xff0c;这里需要注意&#xff0c;索引的结构操作是在存储引擎层完成的&#xff0c;所以不同的存储引擎&#xff0c;索引的结构是不一样的。 &#xff08;1&#xff09;体系结构示意图 &#xff0…

国庆10.01

TCPselect 代码 服务器 #include<myhead.h> #include<sqlite3.h> #define PORT 6666 //端口号 #define IP "192.168.0.104" //IP地址//键盘事件 int jp(fd_set tempfds,int maxfd) {char buf[128] ""; //用来接收数据char buf1[128] …

【算法|贪心算法系列No.2】leetcode2208. 将数组和减半的最少操作次数

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

Spring注册Bean系列--方法1:@Component

原文网址&#xff1a;Spring注册Bean系列--方法1&#xff1a;Component_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Spring注册Bean的方法&#xff1a;Component。 注册Bean的方法我写了一个系列&#xff0c;见&#xff1a;Spring注册Bean(提供Bean)系列--方法大全_IT利刃出鞘…

开绕组电机零序Bakc EMF-based无感控制以及正交锁相环inverse Park-based

前言 最近看论文遇到了基于反Park变换的锁相环&#xff0c;用于从开绕组永磁同步电机零序电压信号中提取转子速度与位置信息&#xff0c;实现无感控制。在此记录 基于零序Back EMF的转子估算 开绕组电机的零序反电动势 e 0 − 3 ω e ψ 0 s i n 3 θ e e_0-3\omega_e\psi_…