Scrapy爬女神图(二)—— 原来还能这样玩

浏览: 1790
Srapy第三篇: ImagesPipeline的使用

大家好呀,我来填坑了(半夜写文也是有些醉啊,课太多没有办法唉。。)
(先随便放个图)


上次的项目一发出,立即有盆友留言:

"看来我们开的不是一辆车"
”还是您这趟比较快“

(详情请看:Scrapy爬女神图(一)—— 这是你们要的小姐姐
。。。。。
我,,,我还只是个纯洁的宝宝好嘛。。

不过,既然咱坑都挖了,还是得填不是?

今天就来谈谈,如何用Scrapy中ImagesPipeline(图片管道),爬取可爱的小姐姐们^_^

一、基础知识

Scrapy提供了一个item pipeline,下载某特定项目的图片,又叫ImagesPipeline(图片管道)

1、可以实现如下功能:
将所有下载的图片转换成通用的格式(JPG)和模式(RGB)
避免重复下载已经下载过的图
生成指定缩略图
检测图片的宽和高,确保它们满足最小限制
由上,为了使用ImagePipeline并获得缩略图,需要安装pillow(不推荐用PIL)
2、使用ImagesPipeline工作流程
(直接截了官网的图)



3、实现 定制图片管道
正如工作流程所示,Pipeline将从item中获取图片的URLs并下载它们,使用get_media_requests处理图片,并返回一个Request对象,这些请求对象将被Pipeline处理,当完成下载后,结果将发送到item_completed方法,当一个单独项目中的所有图片请求完成时(要么完成下载,要么因为某种原因下载失败),ImagesPipeline.item_completed()方法将被调用。
结果results为一个二元组的list,每个元祖包含(success, image_info_or_error)
success: boolean值,success=true表示成功下载 ,反之失败
image_info_or_error 是一个包含下列关键字的字典(如果成功为 True )或者出问题时为 Twisted Failure 。字典包含以下键值对url:原始URL **path:本地存储路径 checksum**:校验码。
失败则包含一些出错信息。

二、代码修改

延续之前例子,不够清楚哒请看上一篇文: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

<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地址

三、结果

结果就是下面这样~


page1

可以从框中看到图片下载异常的提示(scrapy会自动跳过)


page2


我们点开DropItem的网址,发现图片真的不存在


page3




page4


由上来看,一共抓取成功2042张,失败74张
来看文件发生了什么变化:
点开,可以看到生成的原图(full)和缩略图(thumbs)文件


再点开,thumbs中分big和small,大小缩略图,就是之前设置的字典中的键



点开small,可以看到图片真的是根据URL的SHA1 hash值来自动命名的,

(hash值很少会重复,所以可以实现重复判断)


page5


再随便点开一个,如下,真的是缩略图哦~


page6

四、资料推荐

终于差不多啦,送送福利^_^
我收集了一些比较优秀的资料,大家可以做个参考~
官方文档:
Scrapy0.24—— ImagesPipeline部分
优秀博客:
http://www.jianshu.com/p/2528edf4485c
用scrapy自动爬取下载图片

五、总结

最后连带之前的内容一并总结下
这两篇我们使用Scrapy抓取多级网页及图片
1、抓取多级网页:用meta传递数据
2、Scrapy抓取图片:scrapy框架+requests的get方式
3、Scrapy抓取图片: scrapy框架+内置ImagesPipeline方式
两种方式其实下载速度差不多(后面那一种可能快一些)

不过ImagesPipeline可自定义缩略图、过滤小图,还可将打印提示一些出错或不存在而无法下载的图片。 但个人感觉这个项目里面,使用第一种,将图片归类(以title名)存入文件,更加清晰也易查看。

你觉得呢?

(不要愣啦,快快点个赞吧⊙▽⊙)

推荐 1
本文由 waking_up88688 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

0 个评论

要回复文章请先登录注册