scrapy 自定义图片路径保存,并存到数据库中
scrapy中有个自带的pipeline工具,ImagesPipeline,可以专门用来储存图片到本地。
但默认储存地址无法配置,所以我们需要写一个自己的pipeline用于储存图片。
先分析一下我们的需求:
1.修改图片路径,路径根据采集到的item中的数据变化;
2.将数据库中保存图片的url更改为我们的本地文件路径。
首先需要继承原pipeline:
class DownloadImagesPipeline(ImagesPipeline):
然后我们可以查看源码,看看需要改那些地方:
首先是file_path方法,该方法返回了图片储存路径:
def file_path(self, request, response=None, info=None):
## start of deprecation warning block (can be removed in the future)
def _warn():
from scrapy.exceptions import ScrapyDeprecationWarning
import warnings
warnings.warn('ImagesPipeline.image_key(url) and file_key(url) methods are deprecated, '
'please use file_path(request, response=None, info=None) instead',
category=ScrapyDeprecationWarning, stacklevel=1) # check if called from image_key or file_key with url as first argument
if not isinstance(request, Request):
_warn()
url = request
else:
url = request.url # detect if file_key() or image_key() methods have been overridden
if not hasattr(self.file_key, '_base'):
_warn()
return self.file_key(url)
elif not hasattr(self.image_key, '_base'):
_warn()
return self.image_key(url)
## end of deprecation warning block image_guid = hashlib.sha1(to_bytes(url)).hexdigest() # change to request.url after deprecation
return 'full/%s.jpg' % (image_guid)
然后是item_completed方法,该方法返回了item。
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
最后是他们的请求方法get_media_requests,我们需要传入item的内容用于文件夹的命名:
def get_media_requests(self, item, info):
return [Request(x) for x in item.get(self.images_urls_field, [])]
好,我们现在开始重写这三个方法:
首先重写get_media_requests,传入文件夹名称,这里加了一个判断避免报错,同时将return改成了yield,使用return也是可以的,这一块主要是为了校验fetch_date,以及传入fetch_date:
def get_media_requests(self, item, info):
if isinstance(item, LiveItem) and item.get('image') and item.get('fetch_date'):
yield Request(item['image'].replace('\\', '/'), meta={'fetch_date': item.get('fetch_date')})
然后是file_path, 我们只需要复制源码过来修改一下储存路径即可:
def file_path(self, request, response=None, info=None):
## start of deprecation warning block (can be removed in the future)
def _warn():
from scrapy.exceptions import ScrapyDeprecationWarning
import warnings
warnings.warn('ImagesPipeline.image_key(url) and file_key(url) methods are deprecated, '
'please use file_path(request, response=None, info=None) instead',
category=ScrapyDeprecationWarning, stacklevel=1) # check if called from image_key or file_key with url as first argument
if not isinstance(request, Request):
_warn()
url = request
else:
url = request.url # detect if file_key() or image_key() methods have been overridden
if not hasattr(self.file_key, '_base'):
_warn()
return self.file_key(url)
elif not hasattr(self.image_key, '_base'):
_warn()
return self.image_key(url)
## end of deprecation warning block image_guid = hashlib.sha1(to_bytes(request.url)).hexdigest()
return '%s/%s.jpg' % (int(time.mktime(time.strptime(request.meta['fetch_date'], "%Y-%m-%d %H:%M:%S"))),image_guid)
我们的图片下载完成后,会使用一个元组(即results)传入 item_completed 方法,其中包含一些图片的信息,我们可以打印看看:
[(True, {'url': 'https://rpic.douyucdn.cn/asrpic/180918/5070841_1710.jpg/dy1', 'path': '1537261918/7ccaf3dbc7aef44c597cbd1ec4f01ca2fe1995c5.jpg', 'checksum': '92eeb26633a9631ba457f4f524b2d8c2'})]
所以这里我们可以直接对item中的url进行修改为path中的内容即可:
def item_completed(self, results, item, info):
image_paths = [info.get('path', None) for success, info in results if success and info]
if not image_paths:
return item
if isinstance(item, LiveItem):
item['image'] = u''.join(image_paths)
return item
scrapy 自定义图片路径保存,并存到数据库中的更多相关文章
- tomcat 设定自定义图片路径
		1.问题 平常图片路径都是在项目目录下存放,都是ip地址+端口号+项目名+图片路径,因为项目需要要把图片从tomcat中分离出来,并且设置可以通过自定义地址访问自定义图片路径. 2.解决 在 tomc ... 
- 配置NHibernate将枚举保存为Oracle数据库中的字符串
		假设有这样一个枚举: /// <summary> /// 字典项类型 /// </summary> public enum DicItemType { [EnumDescrip ... 
- ASP.NET实现弹出框真分页将复选框选择的数据存到数据库中(四)
		这是第四步点击保存将信息存入数据库中. 这个就简单了利用ajax将JSON字符串传到后台然后这里有个知识点就是将DataTable直接存入数据库中.代码如下: 一.界面获取数据JS代码: //保存订单 ... 
- C#将图片存放到SQL SERVER数据库中的方法
		本文实例讲述了C#将图片存放到SQL SERVER数据库中的方法.分享给大家供大家参考.具体如下: 第一步: ? 1 2 3 4 5 6 7 8 9 10 //获取当前选择的图片 this.pictu ... 
- .net的session详解 存储模式 存到数据库中 使用范围与大小限制 生命周期
		Session又称为会话状态,是Web系统中最常用的状态,用于维护和当前浏览器实例相关的一些信息.举个例子来说,我们可以把已登录用户的用户名放在Session中,这样就能通过判断Session中的某个 ... 
- 1.scrapy爬取的数据保存到es中
		先建立es的mapping,也就是建立在es中建立一个空的Index,代码如下:执行后就会在es建lagou 这个index. from datetime import datetime fr ... 
- Session保存到指定数据库中
		方法1:向数据库中添加session相关信息,可以使用官方工具 命令提示符cmd中执行: cd C:\Windows\Microsoft.NET\Framework\v4.0.30319 ... 
- android 根据SD卡中图片路径读取并显示SD中的图片——源代码
		package com.guo; import java.io.File; import android.app.Activity; import android.graphics.Bitmap; i ... 
- 调用save()方法,页面显示保存成功,但是数据库中没有值的原因
		在DAO层调用save()方法,页面上显示成功,但是在数据库中查找时发现数据没有保存到数据库中的原因可能是: 1.Service层中是否在调用DAO层中的save()方法之前添加注解@Transact ... 
随机推荐
- map+case结构使用技巧
			people.txt文本如下 lyzx1, lyzx2, lyzx3, lyzx4, lyzx5, lyzx6, lyzx7, lyzx7,,哈哈 托塔天王 import org.apache.spa ... 
- Scala常用变量生命周期
			val words = *** //在words被定义时取值 lazy val words = *** //在words被首次使用时取值 def words = *** //在每一次words被使用时 ... 
- (转)Java静态内部类的实例化问题
			最近遇到的一个问题,记录一下. 静态内部类可以被实例化! 1.首先在外部类中的static方法中不能使用普通内部类,因为内部类必须要与外部类建立关联才能使用,可以说是同生共死. 2.我在编码过程中,需 ... 
- solr创建业务域以及指定中文分析器IK
			第一步:把中文分析器添加到工程中. 1.把IKAnalyzer2012FF_u1.jar添加到solr工程的lib目录下 2.把扩展词典.配置文件放到solr工程的WEB-INF/classes目录下 ... 
- [LeetCode] 620. Not Boring Movies_Easy tag: SQL
			X city opened a new cinema, many people would like to go to this cinema. The cinema also gives out a ... 
- [LeetCode] 209. Minimum Size Subarray Sum_Medium
			Given an array of n positive integers and a positive integer s, find the minimal length of a contigu ... 
- 20165321 学习基础与C语言学习心得
			一.技能学习 我其实在小时候学过挺多东西,在我小学的时候,我曾经短时间地学过小提琴.拉丁舞.国画.书法,但是,由于各种原因,都没有继续学习下去.后来,在我小学四年级的时候,我接触到了二胡,于是,我开始 ... 
- 如何解决“504 Gateway Time-out”错误
			做网站的同学经常会发现一些nginx服务器访问时候提示504 Gateway Time-out错误,一般情况下是由nginx默认的fastcgi进程响应慢引起的,但也有其他情况,这里我总结了一些解决办 ... 
- MFC 显示图片
			//定义成员变量 CStatic m_picture; m_picture.Create(L"XXX",WS_VISIBLE|WS_CHILD|SS_BITMAP ,CRect(, ... 
- 删掉centos原有的openjdk并安装sun jdk
			[环境变量]删掉centos原有的openjdk并安装sun jdk 一.卸载原有openjdk rpm -qa | grep java 之后,将展示出来的全部卸载掉,我这里是5个 rpm -e ... 
