10、scrapy框架(六)

一、spider类(基础类)下载图片

不需要allowed_domains限制,就可以删去

用不用管道都可以,管道的open和close不影响

二、ImagesPipeline类(媒体管道类,还能下载音频视频等)下载图片

图片、音频、视频等都是二进制数据

把获取媒体数据的代码封装到媒体管道类中

导入from scrapy.pipelines.images import ImagesPipeline

然后class Bdimgpipeline(ImagesPipeline):用一个类来继承媒体管道类
    pass

settings中打开管道(管道的名字要和创建的一样)来使用,然后设置媒体管道类特有的路径设置,

IMAGES_STORE = ‘/path/to/valid/dir’(复制的路径往往是反斜杠的,所以要换(不换的可以在前面写一个r防止转义),否则转义,路径最后要写多一个‘/文件名’来创建文件名装图片)

编写items.py文件:(注意:使用媒体管道类的话,这个字段名必须是image_urls,因为源码中默认的字段名就是这个)
class BDpipeline(object):
    num=0
    def process_item(self, item, spider):
        if isinstance(item,BdItem):
            if not  os.path.exists("dir_pipe"):
                os.mkdir("dir_pipe")
            filename="dir_pipe/%s.jpg"%str(self.num)
            self.num += 1
            with open(filename,"wb")as f:
                f.write(item["img_data"])
            return item
            这个代码全部都可以通过导入媒体管道类来继承,无需输入以下这些代码操作

from scrapy.pipelines.images import ImagesPipeline用媒体管道类,两行代码就行

class Bdimgpipeline(ImagesPipeline):
    pass
    
    
    
    
更方便的是,可以不用写管道:(在settings设置)
ITEM_PIPELINES = {
  这是原始的方式使用媒体管道类,不用继承
   'scrapy.pipelines.images.ImagesPipeline': 300,          # 注意:一定要开启此pipeline管道!
}
# 注意:一定要指定媒体管道存储的路径!
IMAGES_STORE = r'C:/my/pycharm_work/爬虫/baiduimgs/baiduimgs/dir0'

需要爬取多页图片,就在爬虫文件里构造多页format代码就行,和原来的一样不变其他的

存储管道>>开启管道>>新建管道

媒体管道特性:

媒体管道都实现了以下特性:

避免重新下载最近下载的媒体
指定存储位置(文件系统目录,Amazon S3 bucket,谷歌云存储bucket)
图像管道具有一些额外的图像处理功能:

将所有下载的图片转换为通用格式(JPG)和模式(RGB)
生成缩略图
检查图像的宽度/高度,进行最小尺寸过滤

媒体管道的设置:(在settings设置加入)、

ITEM_PIPELINES = {‘scrapy.pipelines.images.ImagesPipeline’: 1} (在settings的管道开启设置加入,1是优先级数) 启用
FILES_STORE = ‘/path/to/valid/dir’ 文件管道存放位置(继承文件类)
IMAGES_STORE = ‘/path/to/valid/dir’ 图片管道存放位置
FILES_URLS_FIELD = ‘field_name_for_your_files_urls’ 自定义文件url字段
FILES_RESULT_FIELD = ‘field_name_for_your_processed_files’ 自定义结果字段
IMAGES_URLS_FIELD = ‘field_name_for_your_images_urls’ 自定义图片url字段
IMAGES_RESULT_FIELD = ‘field_name_for_your_processed_images’ 结果字段
FILES_EXPIRES = 90 文件过期时间 默认90天
IMAGES_EXPIRES = 90 图片过期时间 默认90天
IMAGES_THUMBS = {‘small’: (50, 50), ‘big’:(270, 270)} 缩略图尺寸(除了执行原始图,还分别生成出两种图,一种是缩略图,一种为放大图)
IMAGES_MIN_HEIGHT = 110 过滤最小高度
IMAGES_MIN_WIDTH = 110 过滤最小宽度
MEDIA_ALLOW_REDIRECTS = True 是否重定向

三、ImagesPipeline类源码简介

生成媒体请求和获取文件名的源码方法可以进行重写或改写

def get_media_requests(self, item, info):
    urls = ItemAdapter(item).get(self.images_urls_field, [])
  列表表达式  return [Request(u) for u in urls]
    
  重写后:(使其能在爬虫文件中允许)
      def get_media_requests(self, item, info):
              for x in item【“image_urls”】:
              		yield scrapy.request(x)
              		得到的请求结果传给下面的 results
       def item_completed(self, results(接收返回值的参数), item, info):
               
               
其中         for u in ItemAdapter(item).get(self.images_urls_field, [])
        相当于 for x in item【“image_urls”】:
  
  
  
  
   def item_completed(self, results, item, info):
        with suppress(KeyError):
            ItemAdapter(item)[self.images_result_field] = [x for ok, x in results if ok]
        return item
    重写后:
    def item_completed(self, results, item, info):
    	for ok, x in results:
    		if  ok:(如果results中有true则判断为ok)
    
    
   要得到路径就可以设 image_path =[x['path']for ok, x in results  if  ok]
   
   	接着可以将得到的结果改写路径:
    	for image_path in image_paths:
    		os.rename(IMAGES_STORE(settings传入的路径)+“/”+image_pat(原路径),IMAGES_STORE+“/”+str(self.image_num)(新路径)+“.jpg”)
    	
   			

四、ImagesPipeline类方法重写

API:

在媒体管道中,我们可以重写的方法:
get_media_requests(item, info) 根据item中的file_urls/image_urls生成请求

def get_media_requests(self, item, info):
for file_url in item[‘file_urls’]:
yield scrapy.Request(file_url)

item_completed(requests, item, info) 当item里的 所有媒体文件请求完成调用

from scrapy.exceptions import DropItem
def item_completed(self, results, item, info):
file_paths = [x[‘path’] for ok, x in results if ok]
if not file_paths:
raise DropItem(“Item contains no files”)
item[‘file_paths’] = file_paths
return item

自定义图片管道案例:

它的工作流是这样的:

1.在爬虫中,您可以返回一个item,并将所需的url放入file_urls字段。
2.item从爬虫返回并进入item管道。
3.当item到达文件管道时,file_urls字段中的url将使用标准的Scrapy调度器和下载程序(这意味着将重用调度器和下载程序中间件)计划下载, 但是具有更高的优先级,在其他页面被爬取之前处理它们。在文件下载完成(或由于某种原因失败)之前,该项在特定管道阶段保持“锁定”状态。
4.下载文件后,将使用另一个字段(files)填充results。这个字段将包含一个包含有关下载文件信息的dicts列表,例如下载的路径、原始的剪贴url(从file_urls字段中获得)和文件校验和。文件字段列表中的文件将保持原来file_urls字段的顺序。如果某些文件下载失败,将记录一个错误,文件将不会出现在files字段中。

yield:执行第一次迭代时(其实就是调用next()方法),如果有左节点并且距离满足要求,会执行第一个yield,这时会返回self._leftchild并完成第一个迭代。
执行第二次迭代时,从第一个yield后面开始,如果有右节点并且距离满足要求,会执行第二个yield,这时会返回self._rightchild并完成第一个迭代。
执行第三次迭代时,第二个yield后再无代码,捕获异常,退出迭代

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

T o r

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值