除了爬取文本,我们可能还需要下载文件、视频、图片、压缩包等,这也是一些常见的需求。scrapy提供了FilesPipeline和ImagesPipeline,专门用于下载普通文件及图片。两者的使用方法也十分简单,首先看下FilesPipeline的使用方式。
FilesPipeline
FilesPipeline的工作流如下:
1. 在spider中爬取要下载的文件链接,将其放置于item中的file_urls;
2. spider将其返回并传送至pipeline链;
3. 当FilesPipeline处理时,它会检测是否有file_urls字段,如果有的话,会将url传送给scarpy调度器和下载器;
4. 下载完成之后,会将结果写入item的另一字段files,files包含了文件现在的本地路径(相对于配置FILE_STORE的路径)、文件校验和checksum、文件的url。
从上面的过程可以看出使用FilesPipeline的几个必须项:
1. Item要包含file_urls和files两个字段;
2. 打开FilesPipeline配置;
3. 配置文件下载目录FILE_STORE。
ImagesPipeline
工作流程:
1. 爬取一个Item,将图片的URLs放入image_urls字段
2. 从Spider返回的Item,传递到Item Pipeline
3. 当Item传递到ImagePipeline,将调用Scrapy调度器和下载器完成image_urls中的url的调度和下载。
4. 图片下载成功结束后,图片下载路径、url和校验和等信息会被填充到images字段中。
实现:
自定义pipeline,优势在于可以重写ImagePipeline类中的实现方法,可以根据情况对照片进行分类;
直接使用ImagePipeline类,简单但不够灵活;所有的图片都是保存在full文件夹下,不能进行分类
|
FilesPipelin |
ImagesPipeline |
Package |
scrapy.pipelines.files.FilesPipeline |
scrapy.pipelines.images.ImagesPipeline |
Item |
file_urls files |
image_urls images |
存储路径配置参数 |
FILES_STROE |
IMAGES_STORE |
除此之外,ImagesPipeline还支持以下特别功能:
1) 生成缩略图,通过配置IMAGES_THUMBS = {'size_name': (width_size,heigh_size),}
2) 过滤过小图片,通过配置IMAGES_MIN_HEIGHT和IMAGES_MIN_WIDTH来过滤过小的图片。
案例
校花网
# spider 爬虫文件
# -*- coding: utf-8 -*-
import scrapy
from ImagePro.items import ImageproItem
class XiaohuaSpider(scrapy.Spider):
name = 'xiaohua'
# allowed_domains = ['www.xxx.com']
start_urls = ['http://www.xiaohuar.com/hua/']
def parse(self, response):
img_url_list = response.xpath('//div[@class="demo clearfix"]/div/div/div/div[1]/a/img/@src').extract()
for de_url in img_url_list:
item = ImageproItem()
item['src'] = 'http://www.xiaohuar.com' + de_url
yield item
# items 文件
import scrapy
class ImageproItem(scrapy.Item):
# define the fields for your item here like:
src = scrapy.Field()
# pipeline 管道文件
import scrapy
from scrapy.pipelines.images import ImagesPipeline
class ImageproPipeline(object):
def process_item(self, item, spider):
print(item['src'])
return item
# 使用一个scrapy封装好的一个专门用于大文件下载的管道类
class ImgPileLine(ImagesPipeline):
# 进行大文件的请求
def get_media_requests(self, item, info):
print(item['src'])
yield scrapy.Request(url=item['src'])
# 用户指定被下载文件的名称
def file_path(self, request, response=None, info=None):
url = request.url
file_name = url.split('/')[-1]
return file_name
def item_completed(self, results, item, info):
print(results)
return item # process_item中的return item作用一致
# settings 配置文件
ITEM_PIPELINES = {
'ImagePro.pipelines.ImageproPipeline': 301,
'ImagePro.pipelines.ImgPileLine': 300,
}
# 图片保存的路径, 如果路径不存在, 自动创建文件路径
IMAGES_STORE = './imgs'