• 汽车之家下载文件和图片


    # scrapy框架里下载问价和图片
    # 判断文件夹和路径是否存在
    
    # 爬虫文件
    import scrapy
    from bmw.items import BmwItem
    
    class Bme5Spider(scrapy.Spider):
        name = 'bme5'
        allowed_domains = ['car.autohome.com.cn']
        start_urls = ['https://car.autohome.com.cn/pic/series/65.html']
    
        def parse(self, response):
            # selectors --> list
            uiboxs = response.xpath("//div[@class='content']/div[@class='row']//div[@class='uibox']")[1:]
            for uibox in uiboxs:
                category = uibox.xpath(".//div[@class='uibox-title']/a/text()").get()
                # print(category)
                urls = uibox.xpath(".//ul/li/a/img/@src").getall()
                # for url in urls:
                #     url = "https://car.autohome.com.cn" + url
                #     print(url)
                urls = list(map(lambda url:"https:" + url,urls))
                # print(urls)
                item = BmwItem(category=category,urls=urls)
                yield item
    
                
    # 管道文件  把图片保存 
    import os
    from urllib import request
    
    class BmwPipeline(object):
        def __init__(self):
            # 获取当前pipeline文件所在的目录路径 os.path.dirname(__file__)
            # 获取最外层bmw的路径os.path.dirname(os.path.dirname(__file__))
            # 在最外层bmw目录下创建一个文件夹 images, 获取images的路径
            self.path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images')
            if not os.path.exists(self.path):
                print("images文件夹不存在")
                os.mkdir(self.path)  # 创建images文件夹
    
    
        def process_item(self, item, spider):
            category = item['category']
            urls = item['urls']
    
            category_path = os.path.join(self.path,category)
            if not os.path.exists(category_path):
                os.mkdir(category_path)
            for url in urls:
                # print(url)
                image_name = url.split("_")[-1]
                request.urlretrieve(url,os.path.join(category_path,image_name))
    
            return item
    scrapy 为下载item中包含的文件(比如在爬取到产品时也想同时保存对应的图片) 提供了一个可重用的item pipeline
    这些pipeline有些共同的方法和结构,我们称之为media pipeline
    一般来说有Files pipeline 和 images pipeline
    
    
    为什么要使用scrapy内置的下载文件的方法?
    1.避免重新下载已经下载过的文件或图片 (避免图片的重复下载)
    2.可以方便的指定文件存储的路径
    3.可以将下载的图片转换成通用的格式, 比如png或者jpg
    4.可以方便生成缩略图
    5.可以方便的检测图片的宽高,确保满足最小限制
    6.异步下载 (重要)
    # 下载文件的files pipeline
    步骤:
    1. 定义好一个item,然后在这个items.py文件中定义两个属性,分别是file_urls(用的多)和files(用的少), file_urls是用来存储需要下载的文件的url连接,需要一个列表
    
    2. 当文件下载完成后,会把文件下载的相关信息存储到item的files属性中, 比如下载路径,下载的url和文件的检验码等
    
    3. 在配置文件settings中,配置FILES_STORE,这个配置用来设置文件下载下来的路径
    
    4. 启动pipeline: 在settings文件中, ITEM_PIPELINES中设置scrapy.pipelines.files.FilesPipeline:1
    # 下载图片的images Pipeline
    当使用images Pipeline下载文件的时候步骤:
    1. 定义好一个item,然后在这个items.py文件中定义两个属性,分别是image_urls和images, images_urls是用来存储需要下载的文件的url连接,需要一个列表
    
    2. 当文件下载完成后,会把文件下载的相关信息存储到item的files属性中, 比如下载路径,下载的url和文件的检验码等
    
    3. 在配置文件settings中,配置IMAGES_STORE,这个配置用来设置文件下载下来的路径
    
    4. 启动pipeline: 在ITEM_PIPELINES中设置scrapy.pipelines.images.ImagesPipeline:1
    # 宝马5系图片下载
    # 在上面代码的基础上稍微修改, 实现异步爬取
    # 先在items 文件中定义两个属性
    
    # items文件
    import scrapy
    class BmwItem(scrapy.Item):
        # define the fields for your item here like:
        category = scrapy.Field()
        image_urls = scrapy.Field()  
        images = scrapy.Field()
        pass
    
    
    # 爬虫文件
    import scrapy
    from bmw.items import BmwItem
    
    class Bme5Spider(scrapy.Spider):
        name = 'bme5'
        allowed_domains = ['car.autohome.com.cn']
        start_urls = ['https://car.autohome.com.cn/pic/series/65.html']
    
        def parse(self, response):
            # selectors --> list
            uiboxs = response.xpath("//div[@class='content']/div[@class='row']//div[@class='uibox']")[1:]
            for uibox in uiboxs:
                category = uibox.xpath(".//div[@class='uibox-title']/a/text()").get()
                # print(category)
                urls = uibox.xpath(".//ul/li/a/img/@src").getall()
                # for url in urls:
                #     url = "https://car.autohome.com.cn" + url
                #     print(url)
                urls = list(map(lambda url:"https:" + url,urls))
                # print(urls)
                item = BmwItem(category=category,image_urls=urls)
                yield item
    
    
    # settings文件 原先的管道文件不再执行了
    ITEM_PIPELINES = {
       # 'bmw.pipelines.BmwPipeline': 300, 
    "scrapy.pipelines.images.ImagesPipeline":1 #不执行管道文件
    }
    
    # 图片下载的路径 供image.pipelines使用
    import os
    IMAGES_STORE = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'images')
    
    
    # 管道文件部分不用修改
    # 执行效率比上面的快很多, 但是这样爬下来的图片没有分类, 都存在一个叫full的文件夹下面了. 现在需要把爬下来的图片进行一下分类
    # 修改pipeline文件, 重写一个类
    
    -------------------------------------------------------------------------------------------------------------
    import os
    from urllib import request
    from scrapy.pipelines.images import ImagesPipeline
    from bmw import settings
    
    class BMWImagesPipeline(ImagesPipeline):
        # 这个方法是发送下载请求之前调用
        # 其实这个方法本身就是发送下载请求的
        def get_media_requests(self,item,info):
            request_objs = super(BMWImagesPipeline, self).get_media_requests(item,info)
            for request_obj in request_objs:
                request_obj.item = item # 把item绑定到request上面,为了下面的方法可以通过request获取item
            return  request_objs
    
        # 这个方法是图片被存储的时候调用,来获取这个图片存储的路径
        def file_path(self,request,response=None,info=None):
            path = super(BMWImagesPipeline, self).file_path(request,response,info)
            # 获取到item, 进一步获取item里的category
            category = request.item.get("category")
            # 获取图片的存储路径
            images_store = settings.IMAGES_STORE
            # 判断这里有没有目录
            category_path = os.path.join(images_store,category)
            if not os.path.exists(category_path):
                os.mkdir(category_path)
            image_name = path.replace("full/","")
            image_path = os.path.join(category_path,image_name)
            return image_path
    
     
    # 但是现在获取的只是一部分的缩略图
    # 现在要获取所有的高清图片
    # 对比一下缩略图和高清图的地址url
    # 缩略图: https://car2.autoimg.cn/cardfs/product/g28/M06/42/A7/t_autohomecar__ChsEnluqOjGABKqaAAeSzV7pUbA132.jpg
    # 高清图(比缩略图少了t_): https://car2.autoimg.cn/cardfs/product/g28/M06/42/A7/autohomecar__ChsEnluqOjGABKqaAAeSzV7pUbA132.jpg
    
    # '更多'页面的url (#后面部分可以删除)
    https://car.autohome.com.cn/pic/series/65-1.html#pvareaid=2042222
    https://car.autohome.com.cn/pic/series/65-10.html#pvareaid=2042222
    https://car.autohome.com.cn/pic/series/65-3.html#pvareaid=2042222
        
    # 对比'更多'url 的规律, 等会使用CrawlSpider
    https://car.autohome.com.cn/pic/series/65-1.html
    https://car.autohome.com.cn/pic/series/65-10.html
    https://car.autohome.com.cn/pic/series/65-3.html
        
    # 随便选一个'更多', 看看里面第二页的url, 找规律
    https://car.autohome.com.cn/pic/series/65-3-p2.html
    https://car.autohome.com.cn/pic/series/65-3-p3.html
        
    https://car.autohome.com.cn/pic/series/65-10-p2.html
    https://car.autohome.com.cn/pic/series/65-10-p3.html
    # 获取高清图片 
    # 类继承的时候  用CrawlSpider不用spider.Spider
    
    from scrapy.spiders import CrawlSpider,Rule
    from scrapy.linkextractors import LinkExtractor
    from bmw.items import BmwItem
    
    
    class Bme5Spider(CrawlSpider):
        name = 'bme5'
        allowed_domains = ['car.autohome.com.cn']
        start_urls = ['https://car.autohome.com.cn/pic/series/65.html']
    
        rules = (
            Rule(LinkExtractor(allow=r'https://car.autohome.com.cn/pic/series/65.+'),
                 callback="parse_page",follow=True),
    
        )
    
        def parse_page(self, response): # 获取高清图
            category = response.xpath('//div[@class="uibox"]/div[1]/text()').get()
            print(category)
            srcs = response.xpath('//div[@class="uibox"]/div[2]/ul/li/a/img/@src').getall()
            # for src in srcs: # src 缩略图的链接, 把t_去掉获得高清图链接
            #     print("https"+src) #//car0.autoimg.cn/upload/2012/8/22/t_201208221937065324122.jpg
            srcs = list(map(lambda src:src.replace("t_",""),srcs))
    
            # 获得高清图链接列表
            srcs = list(map(lambda x: "https:" + x, srcs))
            item =  BmwItem(category=category,image_urls=srcs)
            yield item
  • 相关阅读:
    git常用命令
    IDEA设置
    redis基础
    SQL 基础
    springboot 配置日志 打印不出来sql
    阿里巴巴开发规范最新版
    rabbitmq用户权限
    rabbitMQ配置文件
    RabbitMQ配置文件(rabbitmq.conf)
    C++模板编程:如何使非通用的模板函数实现声明和定义分离
  • 原文地址:https://www.cnblogs.com/kenD/p/11123652.html
Copyright © 2020-2023  润新知