Srapy第三篇: ImagesPipeline的使用
大家好呀,我来填坑了(半夜写文也是有些醉啊,课太多没有办法唉。。)
(先随便放个图)
上次的项目一发出,立即有盆友留言:
"看来我们开的不是一辆车"
”还是您这趟比较快“
(详情请看:Scrapy爬女神图(一)—— 这是你们要的小姐姐)
。。。。。
我,,,我还只是个纯洁的宝宝好嘛。。。
</br>
不过,既然咱坑都挖了,还是得填不是?
今天就来谈谈,如何用Scrapy中ImagesPipeline(图片管道),爬取可爱的小姐姐们_
</br>
</br>
一、基础知识
Scrapy提供了一个item pipeline,下载某特定项目的图片,又叫ImagesPipeline(图片管道)
1、可以实现如下功能:
将所有下载的图片转换成通用的格式(JPG)和模式(RGB)
避免重复下载已经下载过的图
生成指定缩略图
检测图片的宽和高,确保它们满足最小限制
由上,为了使用ImagePipeline并获得缩略图,需要安装pillow(不推荐用PIL)</br></br>
2、使用ImagesPipeline工作流程
(直接截了官网的图)
</br></br>3、实现 定制图片管道
正如工作流程所示,Pipeline将从item中获取图片的URLs并下载它们,使用get_media_requests处理图片,并返回一个Request对象,这些请求对象将被Pipeline处理,当完成下载后,结果将发送到item_completed方法,当一个单独项目中的所有图片请求完成时(要么完成下载,要么因为某种原因下载失败),ImagesPipeline.item_completed()方法将被调用。</br>
结果results为一个二元组的list,每个元祖包含(success, image_info_or_error)
success: boolean值,success=true表示成功下载 ,反之失败
image_info_or_error 是一个包含下列关键字的字典(如果成功为 True )或者出问题时为 Twisted Failure 。</br></br>字典包含以下键值对url:原始URL ****path:本地存储路径 checksum****:校验码。
失败则包含一些出错信息。
</br>
</br>
二、代码修改
延续之前例子,不够清楚哒请看上一篇文:Scrapy爬女神图(一)—— 这是你们要的小姐姐
改动主要在settings和pipelines上
为了大家理解得更加清楚些,这回尽量多点注释_
<settings部分>
# -*- coding: utf-8 -*-
# Scrapy settings for XiaoHua project
BOT_NAME = 'XiaoHua'
SPIDER_MODULES = ['XiaoHua.spiders']
NEWSPIDER_MODULE = 'XiaoHua.spiders'
#是否遵守机器人规则
ROBOTSTXT_OBEY = False
#一次可以requests请求的最大次数,默认16,
CONCURRENT_REQUESTS=16
#下载延迟设置为1s
DOWNLOAD_DELAY=1
#禁用Cookies防止被ban
COOKIES_ENABLED = False
#设置headers
DEFAULT_REQUEST_HEADERS = {
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding':'gzip, deflate, sdch',
'Accept-Language':'zh-CN,zh;q=0.8',
'Cache-Control':'max-age=0',
'Connection':'keep-alive',
'User-Agent':'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36'}
#管道设置
ITEM_PIPELINES = {'XiaoHua.pipelines.XiaohuaPipeline': 1}
#IMAGES_STORE用于设置图片存储路径
IMAGES_STORE=r'F:\\Desktop\code\info\XiaoHua2'
#IMAGES_THUMBS用于生成大小不同的缩略图
#以字典形式表示,键为文件名,值为图片尺寸
IMAGES_THUMBS={
'small': (50, 50),
'big': (200, 200),}
#以下两个设置可以过滤尺寸小于100的图片
IMAGES_MIN_HEIGHT=100
IMAGES_MIN_WIDTH=100
#IMAGES_EXPIRES用于设置失效期限
#这里是90天,避免管道重复下载最近已经下载过的
IMAGES_EXPIRES=90
</br>
<pipelines部分>
改动最大
# -*- coding: utf-8 -*-
import scrapy
from scrapy.exceptions import DropItem
#需要导入ImagesPipeline
from scrapy.pipelines.images import ImagesPipeline
from XiaoHua import settings
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
class XiaohuaPipeline(ImagesPipeline):
#用get_media_requests方法进行下载控制,返回一个requests对象
#对象被Pipeline处理,下载结束后,默认直接将结果传给item_completed方法
def get_media_requests(self, item,info):
yield scrapy.Request(item['detailURL'])
def item_completed(self,results,item,info):
#创建图片存储路径
path=[x['path'] for ok,x in results if ok]
#判断图片是否下载成功,若不成功则抛出DropItem提示
if not path:
raise DropItem('Item contains no images')
print u'正在保存图片:', item['detailURL']
print u'主题', item['title']
return item
items部分和spiders部分相应做下精简
完整版代码下载,轻戳这里:github地址
</br>
三、结果
结果就是下面这样~
可以从框中看到图片下载异常的提示(scrapy会自动跳过)
我们点开DropItem的网址,发现图片真的不存在
由上来看,一共抓取成功2042张,失败74张
来看文件发生了什么变化:
点开,可以看到生成的原图(full)和缩略图(thumbs)文件
再点开,thumbs中分big和small,大小缩略图,就是之前设置的字典中的键
点开small,可以看到图片真的是根据URL的SHA1 hash值来自动命名的,
(hash值很少会重复,所以可以实现重复判断)
再随便点开一个,如下,真的是缩略图哦~
</br>
</br>
四、资料推荐
终于差不多啦,送送福利_
我收集了一些比较优秀的资料,大家可以做个参考~
官方文档:
Scrapy0.24—— ImagesPipeline部分
优秀博客:
http://www.jianshu.com/p/2528edf4485c
用scrapy自动爬取下载图片
</br>
</br>
五、总结
最后连带之前的内容一并总结下
这两篇我们使用Scrapy抓取多级网页及图片
1、抓取多级网页:用meta传递数据
2、Scrapy抓取图片:scrapy框架+requests的get方式
3、Scrapy抓取图片: scrapy框架+内置ImagesPipeline方式
两种方式其实下载速度差不多(后面那一种可能快一些)
</br>
不过ImagesPipeline可自定义缩略图、过滤小图,还可将打印提示一些出错或不存在而无法下载的图片。 但个人感觉这个项目里面,使用第一种,将图片归类(以title名)存入文件,更加清晰也易查看。
你觉得呢?
(不要愣啦,快快点个赞吧⊙▽⊙)