(二)scrapy 中如何自定义 pipeline 下载图片
这里以一个很简单的小爬虫为例,爬取 壹心理 网站的阅读页面第一页的所有文章及其对应的图片,文章页面如下:

创建项目
首先新建一个 scrapy 项目,安装好相关依赖(步骤可参考:scrapy 安装及新建爬虫项目并运行)。
新建一个爬虫:
scrapy genspider xinli001 'www.xinli001.com/info'
此时项目工程目录与新建的爬虫如下:

爬取信息并编写图片自动下载逻辑
本次主要是记录自定义 pipeline 来爬取图片,所以只是简单的选取一些信息来爬取,包括文章标题、图片、发布时间和作者。
1.通过 xpath 提取出文章模块,就是下图中方框中的:

上图右边便是对应的代码位置,下面将先使用 xpath 提取所有 item 模组,之后在对所有 item 组块遍历分别提取其对应的相关信息。
提取 item:
post_nodes = response.xpath('//*[@id="articleListM"]//div[@class="item"]')
2.遍历 post_nodes 并从中提取出相关信息:
下面给出第一个 item 中的网页结构:

对照上面结构提取相关信息:
# 图片
image_url= post_node.xpath('a/img/@src').extract_first()
# 标题
title = post_node.xpath('div[@class="right"]/a/text()').extract_first()
# 发布时间
create_date = post_node.xpath('div[@class="right"]/div[@class="info"]/span/text()').extract_first()
# 作者
writer = post_node.xpath('div[@class="right"]/div[@class="info"]/a[1]/span/text()').extract_first()
3.定义 Xinli001Item
在 item.py 文件中添加 xinli001 爬虫对应的 item:
class Xinli001SpiderItem(scrapy.Item):
title = scrapy.Field()
image_url = scrapy.Field()
writer = scrapy.Field()
create_date = scrapy.Field()
4.提交 item 实例
# -*- coding: utf-8 -*-
import scrapy
from scrapy.http import Request
from urllib import parse
from Xinli001Spider.items import Xinli001SpiderItem
class Xinli001Spider(scrapy.Spider):
name = 'xinli001'
allowed_domains = ['www.xinli001.com']
start_urls = ["https://www.xinli001.com/info/"]
def parse(self, response):
# 提取文章 model
post_nodes = response.xpath('//*[@id="articleListM"]//div[@class="item"]')
for post_node in post_nodes:
# 创建 item 实例
article_item = Xinli001SpiderItem()
# 图片
image_url= post_node.xpath('a/img/@src').extract_first()
# 标题
title = post_node.xpath('div[@class="right"]/a/text()').extract_first()
# 发布时间
create_date = post_node.xpath('div[@class="right"]/div[@class="info"]/span/text()').extract_first()
# 作者
writer = post_node.xpath('div[@class="right"]/div[@class="info"]/a[1]/span/text()').extract_first()
article_item['image_url'] = [image_url]
article_item['title'] = title
article_item['create_date'] = create_date
article_item['writer'] = writer
# 提交 item 实例给 pipeline 处理
yield article_item
5.配置图片下载相关参数:
# 实现自动的图片下载的相关配置
IMAGES_URLS_FIELD = "image_url" # 图片
project_dir = os.path.abspath(os.path.dirname(__file__)) # 获取当前路径
IMAGES_STORE = os.path.join(project_dir, 'images') # 将图片保存到当前项目路径下的 images 文件夹下
将上面的代码加入到 settings.py 中 Configure item pipelines 相关代码的下方。
6.启用 scrapy 的图片下载
在第5步之后,需要在 settings.py 中开启图片下载的服务:

7.再次运行爬虫,便可实现图片的自动下载

获取图片存放路径
图片下载之后,若要想访问图片,则需要获得图片的存放路径,此时我们便可对上面的 ImagePipeline 实现自定义来将获取图片存放路径的逻辑填充进代码中。
1-首先,添加 ArticleImagePipeline 类:
# 自定义 ImagePipeline ,继承自 ImagesPipeline,并添加相关自定义操作
class ArticleImagePipeline(ImagesPipeline):
# 重写 item_completed 方法
def item_completed(self, results, item, info):
# 默认传过来的 result 是一个list
# ok 表示返回是否成功,value是一个dict,存放了图片保存的路径
for ok, value in results:
image_file_path = value["path"]
# 将获得的文件存放路径填充到 item 中
item["front_image_path"] = image_file_path
# 返回item
return item
2-将 ArticleImagePipeline 配置到 settings.py 文件中:
# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'Xinli001Spider.pipelines.Xinli001SpiderPipeline': 300,
# 'Xinli001Spider.pipelines.ImagesPipeline': 1,
'Xinli001Spider.pipelines.ArticleImagePipeline': 1,
}
注意上面之前使用的 ImagesPipeline 不需要了,要注释掉。
3-添加相关 item 属性
在 Xinli001SpiderItem 中添加一个 front_image_path 属性来存储图片存放路径:

4-查看返回的图片路径
第二步中我们配置了两个 Pipeline ,一个顺序在前(ArticleImagePipeline:1),一个在后(Xinli001SpiderPipeline:300),我们可以在后面的 Pipeline 处理函数处打个断点,然后启动调试功能来运行。
打断点:

debug 一下:

可以看到执行到断点处时,已经提取到了图片存放路径:

(二)scrapy 中如何自定义 pipeline 下载图片的更多相关文章
- 通过scrapy内置的ImagePipeline下载图片到本地、并提取本地保存地址
1.通过scrapy内置的ImagePipeline下载图片到本地 2.获取图片保存本地的地址 1.通过scrapy内置的ImagePipeline下载图片到本地 1)在settings.py中打开 ...
- 使用Scrapy自带的ImagesPipeline下载图片,并对其进行分类。
ImagesPipeline是scrapy自带的类,用来处理图片(爬取时将图片下载到本地)用的. 优势: 将下载图片转换成通用的JPG和RGB格式 避免重复下载 缩略图生成 图片大小过滤 异步下载 . ...
- Expo大作战(十二)--expo中的自定义样式Custom font,以及expo中的路由Route&Navigation
简要:本系列文章讲会对expo进行全面的介绍,本人从2017年6月份接触expo以来,对expo的研究断断续续,一路走来将近10个月,废话不多说,接下来你看到内容,讲全部来与官网 我猜去全部机翻+个人 ...
- 自定义NSOperation下载图片
自定义NSOperation的话,只是需要将要下载图片的操作下载它的main方法里面,考虑到,图片下载完毕,需要回传到控制器里,这里可以采用block,也可以采用代理的方式实现,我采用的是代理的方式实 ...
- cropper.js 二次开发:截图并下载图片
cropper.js 是一个基于jquery的图片截取库. 参考:https://blog.csdn.net/weixin_38023551/article/details/78792400 我的代码 ...
- scrapy中的ImagePipeline下载图片到本地、并提取本地的保存地址
通过scrapy内置到ImagePipeline下载图片到本地 在settings中打开 ITEM_PIPELINES的注释,并在这里面加入 'scrapy.pipelines.images.Imag ...
- iOS下载图片失败
一.具体问题 开发的过程中,发现某个界面部分图片的显示出现了问题只显示占位图片,取出图片的url在浏览器却是能打开的,各种尝试甚至找同行的朋友帮忙在他们项目里展示都会存在问题,最终发现通过第三方框架S ...
- WinCE开机Logo的实现(USB下载图片到nandflash)
WinCE开机启动Logo使用Eboot读取NandFlash中的图片数据,然后显示的方式.对于开机logo的方式网友http://jazka.blog.51cto.com/809003/664131 ...
- Scrapy框架——介绍、安装、命令行创建,启动、项目目录结构介绍、Spiders文件夹详解(包括去重规则)、Selectors解析页面、Items、pipelines(自定义pipeline)、下载中间件(Downloader Middleware)、爬虫中间件、信号
一 介绍 Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速.简单.可扩展的方式从网站中提取所需的数据.但目前Scrapy的用途十分广泛,可 ...
随机推荐
- winform 中心旋转 图片旋转
//设置左上角到中心点 g.TranslateTransform(int.Parse(x), int.Parse(y)); //旋转角度 g.RotateTransform(int.Parse(&qu ...
- opencv 4.0 + linux下静态编译,展示详细ccmake的参数配置
#先安装 cmake 3.14 # cmake安装到了 /usr/local/bin #配置PATH export PATH="$PATH:/usr/local/bin" #下载最 ...
- K8s配置配置存活、就绪和启动探测器
kubelet 使用存活探测器来知道什么时候要重启容器. 例如,存活探测器可以捕捉到死锁(应用程序在运行,但是无法继续执行后面的步骤). 这样的情况下重启容器有助于让应用程序在有问题的情况下更可用. ...
- 直接copy大于某一个时间小于某一个时间的文件--find进阶用法
find ./ -type f -newermt '2000-01-04 10:30:00' ! -newermt '2019-10-28 10:57:00' -exec cp -a {} /var/ ...
- docker 传入变量
1.Dockerfile中定义变量 ENV maxmemory="" 2.脚本接收变量 if [ "$maxmemory" ];then sed -i &quo ...
- 一起来找茬:记一起 clang 开启 -Oz 选项引发的血案
作者:字节跳动终端技术 -- 刘夏 前言 笔者来自字节跳动终端技术 AppHealth (Client Infrastructure - AppHealth) 团队,在工作中我们会对开源 LLVM 及 ...
- pod 详解
静态pod是由kubelet进行管理的仅存在于特定的node上的pod. pod容器共享volume同一个pod中的多个容器能够共享pod级别的存储卷volume pod的配置管理 应用配置管理方案 ...
- .NET 20周年软件趋势随想
从2000年微软启动.NET战略时,我还是一位大学生,当年著名的黑客Miguel de Icaza , Miguel 为了寻找GNOME项目开发框架经过充分的调研启动了一个志存高远的项目:Mono,一 ...
- Matplotlib 绘图秘籍·翻译完成
原文:Matplotlib Plotting Cookbook 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远. 在线阅读 ApacheCN ...
- vue v-model原理实现
v-model的实现原理: 基础用法: v-model 本质上不过是语法糖,可以用 v-model 指令在表单 <input>.<textarea> 及 <select& ...