首页 > 代码库 > scrapy下载图片第一波

scrapy下载图片第一波

scrapy的图片管道,在ImagePipeline类中实现 ,提供了一个方便并具有额外特性的方法,来下载并本地存储图片:

  * 将所有下载的图片转换成通用的格式(JPG)和模式(RGB)

  * 避免重新下载最近已经下载过的图片

  * 缩略图生成

  * 检测图像的宽/高,确保它们满足最小的限制

这个管道也会为那些当前安排好要下载的图片保留一个内部队列,并将那些到达的包含相同图片的项目连接到那个队列中. 这可以避免多次下载几个项目共享的同一个图片.

  Pillow是用来生成缩略图,并将图片归一化为JPEG/RGB格式,因此为了使用图片管道,需要安装Pillow库,不推荐PIL.

当使用图片管道 ImagePipeline,典型的工作流程如下:

  * 在一个爬虫里,你抓取一个项目,把其中图片的URL放入image_urls组内.

  * 项目从爬虫内返回,进入项目管道.

  * 当项目进入ImagePipeline, image_urls组内的URLs将被Scrapy的调度器和下载器安排下载(这意味着调度器和中间件可以复用),当优先级更高,会在其他页面被抓取前处理. 项目会在这个特定的管道阶段保持"locker"的状态,直到完成图片的下载(或者由于某些原因未完成下载).

  * 当图片下载完, 另一个组(images)将被更新到结构中,这个组将包含一个字典列表,其中包括下载图片的信息,比如下载路径,源抓取地址(从image_urls组获得)和图片的校验码. images列表中的图片顺序将和源image_urls组保持一致.如果某个图片下载失败,将会记录下错误信息,图片也不会出现在images组中.

    上面的没事多读读,  下面开始实战.这里我以摄图网为例.

1.首先,修改items.py

1 import scrapy
2 
3 class ImageItem(scrapy.Item):
4     image_urls = scrapy.Field()
5     images = scrapy.Field()
 # image_urls和images是固定的

2. 修改settings.py ,开启你的图片管道

技术分享
1 #增添如下代码
2 
3 USER_AGENT = Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36
4 #开启图片管道
5 ITEM_PIPELINES = {
6     scrapy.contrib.pipeline.images.ImagesPipeline: 1
7 }
8 #将IMAGES_STORE设置为一个有效的文件夹,用来存储下载的图片.否则管道将保持禁用状态,即使你在ITEM_PIPELINES设置中添加了它.
9 IMAGES_STORE = D:\\pics
View Code

图片存储在文件中(一个图片一个文件),并使用它们URL的 SHA1 hash 作为文件名。

3. 修改pipelines.py,实现定制图片管道(这部分代码原封不动copy过去就行了)

 1 from scrapy.contrib.pipeline.images import ImagesPipeline
 2 from scrapy.exceptions import DropItem
 3 from scrapy.http import Request
 4 
 5 class MyImagesPipeline(ImagesPipeline):
 6     def get_media_requests(self, item, info):
 7         for image_url in item[image_urls]:
 8             yield Request(image_url)
 9             
10     def item_completed(self, results, item, info):
11         image_path = [x[path] for ok,x in results if ok]
12         if not image_path:
13             raise DropItem(Item contains no images)
14         item[image_paths] = image_path
15         return item

4. 编写spider

 

 1 # -*- coding: utf-8 -*-
 2 import scrapy
 3 from t2.items import ImageItem
 4 class XiaohuaSpider(scrapy.Spider):
 5     name = "baidumeinv"
 6     allowed_domains = ["699pic.com"]
 7     start_urls = [http://699pic.com/people.html]
 8     download_delay = 2
 9 
10     def parse(self, response):
11         item = ImageItem()
12         srcs = response.xpath(//div[@class="swipeboxEx"]/div[@class="list"]/a/img/@data-original).extract()
13         item[image_urls] = srcs
14         yield item

###这里注意一下,在settings.py存储图片,其ITEM_PIPELINES = {‘scrapy.pipelines.images.ImagesPipeline’: 1}用到的是图片的url列表,所以parse函数需要yield的是一个列表!  如果返回的是一个url字符串,则可能引发

raise ValueError(‘Missing scheme in request url: %s‘ % self._url)

ValueError: Missing scheme in request url: h

 

相信如果懂了上面的单个网页爬取, 那么多页爬取肯定也难不到你...

附上scrapy文档连接:   https://scrapy-chs.readthedocs.io/zh_CN/0.24/topics/images.html

scrapy下载图片第一波