scrapy中有个自带的pipeline工具,ImagesPipeline,可以专门用来储存图片到本地。

但默认储存地址无法配置,所以我们需要写一个自己的pipeline用于储存图片。

先分析一下我们的需求:

1.修改图片路径,路径根据采集到的item中的数据变化;

2.将数据库中保存图片的url更改为我们的本地文件路径。

首先需要继承原pipeline:
class DownloadImagesPipeline(ImagesPipeline):

然后我们可以查看源码,看看需要改那些地方:

首先是file_path方法,该方法返回了图片储存路径:

  1. def file_path(self, request, response=None, info=None):
  2. ## start of deprecation warning block (can be removed in the future)
  3. def _warn():
  4. from scrapy.exceptions import ScrapyDeprecationWarning
  5. import warnings
  6. warnings.warn('ImagesPipeline.image_key(url) and file_key(url) methods are deprecated, '
  7. 'please use file_path(request, response=None, info=None) instead',
  8. category=ScrapyDeprecationWarning, stacklevel=1)
  9.  
  10. # check if called from image_key or file_key with url as first argument
  11. if not isinstance(request, Request):
  12. _warn()
  13. url = request
  14. else:
  15. url = request.url
  16.  
  17. # detect if file_key() or image_key() methods have been overridden
  18. if not hasattr(self.file_key, '_base'):
  19. _warn()
  20. return self.file_key(url)
  21. elif not hasattr(self.image_key, '_base'):
  22. _warn()
  23. return self.image_key(url)
  24. ## end of deprecation warning block
  25.  
  26. image_guid = hashlib.sha1(to_bytes(url)).hexdigest() # change to request.url after deprecation
  27. return 'full/%s.jpg' % (image_guid)

  

然后是item_completed方法,该方法返回了item。

  1. def item_completed(self, results, item, info):
  2. if isinstance(item, dict) or self.images_result_field in item.fields:
  3. item[self.images_result_field] = [x for ok, x in results if ok]
  4. return item

  

最后是他们的请求方法get_media_requests,我们需要传入item的内容用于文件夹的命名:

  1. def get_media_requests(self, item, info):
  2. return [Request(x) for x in item.get(self.images_urls_field, [])]

  

好,我们现在开始重写这三个方法:

首先重写get_media_requests,传入文件夹名称,这里加了一个判断避免报错,同时将return改成了yield,使用return也是可以的,这一块主要是为了校验fetch_date,以及传入fetch_date:

  1. def get_media_requests(self, item, info):
  2. if isinstance(item, LiveItem) and item.get('image') and item.get('fetch_date'):
  3. yield Request(item['image'].replace('\\', '/'), meta={'fetch_date': item.get('fetch_date')})

  

然后是file_path, 我们只需要复制源码过来修改一下储存路径即可:

  1. def file_path(self, request, response=None, info=None):
  2. ## start of deprecation warning block (can be removed in the future)
  3. def _warn():
  4. from scrapy.exceptions import ScrapyDeprecationWarning
  5. import warnings
  6. warnings.warn('ImagesPipeline.image_key(url) and file_key(url) methods are deprecated, '
  7. 'please use file_path(request, response=None, info=None) instead',
  8. category=ScrapyDeprecationWarning, stacklevel=1)
  9.  
  10. # check if called from image_key or file_key with url as first argument
  11. if not isinstance(request, Request):
  12. _warn()
  13. url = request
  14. else:
  15. url = request.url
  16.  
  17. # detect if file_key() or image_key() methods have been overridden
  18. if not hasattr(self.file_key, '_base'):
  19. _warn()
  20. return self.file_key(url)
  21. elif not hasattr(self.image_key, '_base'):
  22. _warn()
  23. return self.image_key(url)
  24. ## end of deprecation warning block
  25.  
  26. image_guid = hashlib.sha1(to_bytes(request.url)).hexdigest()
  27. return '%s/%s.jpg' % (int(time.mktime(time.strptime(request.meta['fetch_date'], "%Y-%m-%d %H:%M:%S"))),image_guid)

  我们的图片下载完成后,会使用一个元组(即results)传入 item_completed 方法,其中包含一些图片的信息,我们可以打印看看:

  1. [(True, {'url': 'https://rpic.douyucdn.cn/asrpic/180918/5070841_1710.jpg/dy1', 'path': '1537261918/7ccaf3dbc7aef44c597cbd1ec4f01ca2fe1995c5.jpg', 'checksum': '92eeb26633a9631ba457f4f524b2d8c2'})]

  所以这里我们可以直接对item中的url进行修改为path中的内容即可:

  1. def item_completed(self, results, item, info):
  2. image_paths = [info.get('path', None) for success, info in results if success and info]
  3. if not image_paths:
  4. return item
  5. if isinstance(item, LiveItem):
  6. item['image'] = u''.join(image_paths)
  7. return item

  

scrapy 自定义图片路径保存,并存到数据库中的更多相关文章

  1. tomcat 设定自定义图片路径

    1.问题 平常图片路径都是在项目目录下存放,都是ip地址+端口号+项目名+图片路径,因为项目需要要把图片从tomcat中分离出来,并且设置可以通过自定义地址访问自定义图片路径. 2.解决 在 tomc ...

  2. 配置NHibernate将枚举保存为Oracle数据库中的字符串

    假设有这样一个枚举: /// <summary> /// 字典项类型 /// </summary> public enum DicItemType { [EnumDescrip ...

  3. ASP.NET实现弹出框真分页将复选框选择的数据存到数据库中(四)

    这是第四步点击保存将信息存入数据库中. 这个就简单了利用ajax将JSON字符串传到后台然后这里有个知识点就是将DataTable直接存入数据库中.代码如下: 一.界面获取数据JS代码: //保存订单 ...

  4. C#将图片存放到SQL SERVER数据库中的方法

    本文实例讲述了C#将图片存放到SQL SERVER数据库中的方法.分享给大家供大家参考.具体如下: 第一步: ? 1 2 3 4 5 6 7 8 9 10 //获取当前选择的图片 this.pictu ...

  5. .net的session详解 存储模式 存到数据库中 使用范围与大小限制 生命周期

    Session又称为会话状态,是Web系统中最常用的状态,用于维护和当前浏览器实例相关的一些信息.举个例子来说,我们可以把已登录用户的用户名放在Session中,这样就能通过判断Session中的某个 ...

  6. 1.scrapy爬取的数据保存到es中

    先建立es的mapping,也就是建立在es中建立一个空的Index,代码如下:执行后就会在es建lagou 这个index.     from datetime import datetime fr ...

  7. Session保存到指定数据库中

    方法1:向数据库中添加session相关信息,可以使用官方工具 命令提示符cmd中执行: cd C:\Windows\Microsoft.NET\Framework\v4.0.30319       ...

  8. android 根据SD卡中图片路径读取并显示SD中的图片——源代码

    package com.guo; import java.io.File; import android.app.Activity; import android.graphics.Bitmap; i ...

  9. 调用save()方法,页面显示保存成功,但是数据库中没有值的原因

    在DAO层调用save()方法,页面上显示成功,但是在数据库中查找时发现数据没有保存到数据库中的原因可能是: 1.Service层中是否在调用DAO层中的save()方法之前添加注解@Transact ...

随机推荐

  1. (转)EOSIO开发(一)使用Docker构建本地环境

    前言 一直想学习EOS开发,但是不知道怎么入门.最近从GitHub上下载了源码,发现官方已经提供了完整的EOSIO开发入门教程,既然如此赶紧开始行动.今天是系列文章的第一篇,介绍如何使用Docker搭 ...

  2. solr整合spring

    <!-- 单机版solr服务配置 --> <!-- <bean id="httpSolrServer" class="org.apache.sol ...

  3. 【LeetCode每天一题】Multiply Strings(字符串乘法)

    Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and ...

  4. 30-Python3 正则表达式

    30-Python3 正则表达式 ''' re.match函数 ''' import re print(re.match('www','www.runoob.com').span()) print(r ...

  5. 移动开发--移动web特别样式处理

    高清图片:100px*200px的图片 设置100px*100px的大小,会被拉大,变模糊,应该用100dp*100dp(物理像素)去渲染. 一像素边框: 相对单位rem: 多行文本溢出.

  6. 好吧,我承认我是爱瞎折腾----利用YDUI改变页面UI

    上周恒丰代付接口上线投产后,我做了一个“恒丰代付检查工具”,用途是,当线上调用恒丰代付出现了问题订单时,可以在这个工具页里做相应的弥补. 我项目里其他一些工具页的UI用的是YDUI.YDUI号称是“一 ...

  7. yield和send函数

    yield作用类似于return,其本质是一个迭代器. 当程序执行到yield时,会结束本次循环,返回一个值,然后内置含有next()函数, 下次在执行时,会从yield结束的地方继续执行. 带yie ...

  8. 解决Nginx重启时提示nginx: [emerg] bind() to 0.0.0.0:80错误

    Nginx是一款轻量级的Web服务器,特点是占有内存少,并发能力强,因而使用比较广泛,蜗牛今天在一个VPS上重启Nginx时提示“nginx: [emerg] bind() to 0.0.0.0:80 ...

  9. linux df查看硬盘使用量 du查看文件所占大小

    df 常用来查看磁盘的占用情况. du 常用来查看文件夹的大小等. Linux命令: df  [-ahikHTm]  [目录或者文件夹] 参数: -h : 以交较易识别的方式展示使用量  111100 ...

  10. gitlab RPM卸载 & 安装 && 升级(9.0.13-》9.5.9-》10.0->10.3.9->10.6.6-》10.8-》11.0)

    版本:9.0.3 升级版本:9.0.13 一,停止服务 gitlab-ctl stop unicorn gitlab-ctl stop sidekiq gitlab-ctl stop nginx 二, ...