美文网首页程序员
爬虫小白:11.scrapy框架(六) _媒体管道

爬虫小白:11.scrapy框架(六) _媒体管道

作者: 見贤思齊_ | 来源:发表于2020-04-04 22:21 被阅读0次

    一、媒体管道(ImagesPipeline)是什么?

    scrapy提供了专门下载的PIpeline,包含文件下载和图片下载。

    二、为什么要有媒体管道?

    简化操作,比如存储等。当然我们可以进行重写。

    1. 将下载图片转换成通用的JPG和RGB格式

    2. 避免重复下载

    3. 缩略图生成

    4. 图片大小过滤

    5. 异步下载

    三、媒体管道的使用

    1)使用

    工作流程:
    1. 爬取一个Item,将图片的URLs放入image_urls字段

    2. 从Spider返回的Item,传递到Item Pipeline

    3. 当Item传递到ImagePipeline,将调用Scrapy 调度器和下载器完成image_urls中的url的调度和下载。

    4. 图片下载成功结束后,图片下载路径、url和校验和等信息会被填充到images字段中。

    1、items.py定义特殊字段名 :
     #内置的ImagePipeline会默认读取Item的image_urls字段,item.py 中只能写image_urls字段 
     image_urls = scrapy.Field()  #固定
    
    2、处理pipelines.py ,分为两种:
     1、自定义pipeline,且让 类 继承ImagesPipeline,优势在于可以重写ImagePipeline类中的实现方法。
     2、直接使用ImagePipeline类,简单但不够灵活。
    
     方法一:
     #这是自定义,优势在于可以重写ImagePipeline类中的实现方法,可以根据情况对照片进行分类;
        '''
         首先要复写父类的两个方法,一个是get_midia_requests(),构建request请求,然后交由下载器下载,第二个是item_completed(),当下载完毕后,默认会调用该方法,我们只需注意第二个results参数,他是一个由二元元祖组成的list,第一个值是一个布尔类型的值,用于判断图片是否下载成功,第二个值是关于图片的下载信息。
        '''
        from scrapy.pipelines.images import ImagesPipeline
        from scrapy.exceptions import DropItem
        from scrapy import Request
        
        class 类名(ImagesPipeline):   #切记得继承ImagesPipeline
            def get_media_requests(self, item, info):
                for url in item['image_urls']:
                    yield Request(url)
                    
            def item_completed(self, results, item, info):
                item['images'] = [x for ok, x in results if ok]
                return item
            
            def process_item(self,item,spider):
                with open() as f:
                    f.write()
                return item 
    
    
     方法二:
     #在管道得开启 'scrapy.pipelines.images.ImagesPipeline' 这是媒体基础管道,可以试一下。且直接使用  ImagePipeline类,虽简单但不够灵活;所有的图片都是保存在 full文件夹下,而且图片名。
    
    3、 配置settings中的ITEM_PIPELINES:
     ITEM_PIPELINES={
     #方法一:  管道开启
     '项目名.piplines.自定义类名':1 , #后面数字1让它马上调用。
    
     #方法二: 这是图片基础管道,scrapy写的,直接开启它就行了。
     'scrapy.pipelines.images.ImagesPipeline': 1 
     }
    
    4、媒体管道的一些设置:
     在settings.py里添加,如IMAGES_STORE = 'IMG'    #设置图片存储位置,这个必须得设</pre>
    

    直接使用ImagePipeline类 , 所有的图片都是保存在 full文件夹下:


    直接使用ImagePipeline类存储结果.png

    2)媒体管道的一些设置:

    在settings中添加就可以了
    ​
    ITEM_PIPELINES = {‘scrapy.pipelines.images.ImagesPipeline’: 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      #是否重定向</pre>
    

    四、按例:爬取百度图片

    1、item.py文件:定义item字段
    import scrapy
    class ImgPipelineItem(scrapy.Item):
     # define the fields for your item here like:
     # name = scrapy.Field()
     image_urls =  scrapy.Field()    #只要使用媒体管道,这个字段是固定设置的
    
    ​
    2、spider.py文件:编写爬虫文件,解析源码,得到图片的url下载路径
    import scrapy
    import re
    from ..items import ImgPipelineItem
    ​
    class MediaSpider(scrapy.Spider):
     name = 'media'
     # allowed_domains = ['www.baidu.com']
     start_urls = ['https://image.baidu.com/search/index?tn=baiduimage&ct=201326592&lm=-1&cl=2&ie=gb18030&word=%B1%CB%B0%B6%BB%A8&fr=ala&ala=1&alatpl=adress&pos=0&hs=2&xthttps=111111']
    ​
     def parse(self, response):
     img_urls = re.findall('"thumbURL":"(.*?)"',response.text)[0:-1]
     # print(img_urls)
     item = ImgPipelineItem()
     item['image_urls'] = img_urls
     yield item
    
    3、pipelines.py文件:对item里的数据进行处理,这里是调用调度器和下载器下载图片。 
           若直接使用ImagePipeline类 , 所以这里不用处理。
    
           自定义:
        import os
        import scrapy
        class ImgPipelinePipeline(ImagesPipeline):
        # def get_media_requests(self, item, info):
        def get_media_requests(self, item, info):
            for file_url in item['image_urls']:
                print("**********")
                yield scrapy.Request(file_url)
    
        def item_completed(self, results, item, info):
            # image_paths = [x['path'] for ok, x in results if ok]
            image_paths=[]
            for ok,x in results:
                if ok:
                    image_paths.append(x['path'])
            print(image_paths)
            # if not image_paths:
            #     raise DropItem("Item contains no files")
            # item['image_paths'] = image_paths
            # return item
    
        #     return [scrapy.Request(x) for x in item.get(self.images_urls_field, [])]
        #
        # pass
        # num = 0
        # def process_item(self, item, spider):
        #     self.num+=1
        #     with open(str(self.num)+".jpg","wb") as f:
        #         f.write(item["content"])
        #     return item
    

    相关文章

      网友评论

        本文标题:爬虫小白:11.scrapy框架(六) _媒体管道

        本文链接:https://www.haomeiwen.com/subject/sxgsphtx.html