Scrapy提供了一个 item pipeline ,来下载属于某个特定项目的图片,比如,当你抓取产品时,也想把它们的图片下载到本地。
这条管道,被称作图片管道,在 ImagesPipeline 类中实现,提供了一个方便并具有额外特性的方法,来下载并本地存储图片:
-将所有下载的图片转换成通用的格式(JPG)和模式(RGB)
- 这里是列表文本避免重新下载最近已经下载过的图片 -缩略图生成 -检测图像的宽/高,确保它们满足最小限制 这个管道也会为那些当前安排好要下载的图片保留一个内部队列,并将那些到达的包含相同图片的项目连接到那个队列中。 这可以避免多次下载几个项目共享的同一个图片。
Pillow 是用来生成缩略图,并将图片归一化为JPEG/RGB格式,因此为了使用图片管道,你需要安装这个库。 Python Imaging Library (PIL) 在大多数情况下是有效的,但众所周知,在一些设置里会出现问题,因此我们推荐使用 Pillow 而不是 PIL.。
在windows下,利用pip安装PIL找不到可以安装的版本,所以选用Pillow,顺利运行
下面是抓取百度贴吧的一个小demo
spider文件夹下的spider baidu.py
import scrapy
import requests
import os
from BaiduTieba.items import BaidutiebaItem
class BaiduTieBaSpider(scrapy.spiders.Spider):
name = 'baidutieba'
start_urls = ['http://tieba.baidu.com/p/2235516502?see_lz=1&pn=%d' % i for i in range(1, 38)]
image_names = {}
def parse(self, response):
item = BaidutiebaItem()
item['image_urls'] = response.xpath("//img[@class='BDE_Image']/@src").extract()
for index, value in enumerate(item['image_urls']):
number = self.start_urls.index(response.url) * len(item['image_urls']) + index
self.image_names[value] = 'full/%04d.jpg' % number
yield item
注意在引用Item类时的路径
items.py
import scrapy
class BaidutiebaItem(scrapy.Item):
image_urls = scrapy.Field()
images = scrapy.Field()
image_paths = scrapy.Field()
ImagePipeline.py
import scrapy
from scrapy.contrib.pipeline.images import ImagesPipeline
from scrapy.exceptions import DropItem
from BaiduTieba.spiders.baidu import BaiduTieBaSpider
class MyImagesPipeline(ImagesPipeline):
def file_path(self, request, response=None, info=None):
image_name = BaiduTieBaSpider.image_names[request.url]
return image_name
def get_media_requests(self, item, info):
for image_url in item['image_urls']:
yield scrapy.Request(image_url)
def item_completed(self, results, item, info):
image_paths = [x['path'] for ok, x in results if ok]
if not image_paths:
raise DropItem("Item contains no images")
item['image_paths'] = image_paths
return item
setting.py
BOT_NAME = 'BaiduTieba'
SPIDER_MODULES = ['BaiduTieba.spiders']
NEWSPIDER_MODULE = 'BaiduTieba.spiders'
ROBOTSTXT_OBEY = False
ITEM_PIPELINES = {
'BaiduTieba.ImagePipeline.MyImagesPipeline': 300,
}
IMAGES_STORE = '/baidutieba.01'
IMAGES_STORE是下载图片的保存路径。