• 15.scrapy框架之日志等级、请求传参、提高scrapy框架的爬取效率


    一、Scrapy的日志等级

      - 在使用   scrapy crawl  爬虫文件名     运行程序时,在终端里打印输出的就是scrapy的日志信息。

      - 日志信息的种类:

            ERROR : 一般错误

            WARNING : 警告

            INFO : 一般的信息

            DEBUG : 调试信息

      - 设置日志信息指定输出:

        在settings.py配置文件中,加入

                        LOG_LEVEL = ‘指定日志信息种类’即可。

                        LOG_FILE = 'log.txt'则表示将日志信息写入到指定文件中进行存储。

        例如:

            LOG_LEVEL = ‘ERROR’      绑定日志输出,只输出error类型的日志分析,其他类型的不输出

    二、请求传参

      - 在某些情况下,我们爬取的数据不在同一个页面中,例如,我们爬取一个电影网站,电影的名称,评分在一级页面,而要爬取的其他电影详情在其二级子页面中。这时我们就需要用到请求传参。

      - 案例展示:爬取http://www.55xia.com/电影网,将一级页面中的电影名称,评分一级二级页面中的导演,电影介绍进行爬取。

    实现代码:

    爬虫文件代码:

    import scrapy
    from filmPro.items import FilmproItem
    
    class FilmSpider(scrapy.Spider):
        name = 'film'
        # allowed_domains = ['www.xxxx.com']
        start_urls = ['http://www.55xia.com/']
    
        def parse(self, response):
            div_list = response.xpath('//div[@class="col-xs-1-5 movie-item"]')
            for div in div_list:
                # 1.获取解析到数据,并在items文件中配置属性
                title = div.xpath('.//div[@class="meta"]/h1/a/text()').extract_first()
                grade = div.xpath('.//div[@class="meta"]/h1/em/text()').extract_first()
                if grade == None:
                    grade = '0'
                # 1.获取详情页面
                detail_url = 'https:' + div.xpath('.//div[@class="meta"]/h1/a/@href').extract_first()
                print(title,grade,detail_url)
    
                # 2.实例化一个item类型的对象
                item = FilmproItem()
                item["title"] = title
                item["grade"] = grade
    
                # 3.对详情的url发送请求,通过meta参数进行Request的数据传递(请求传参)
                yield scrapy.Request(url=detail_url, callback=self.getDetailPage, meta={'item': item})
    
        def getDetailPage(self,response):
            # 4.通过response获取item对象
            item = response.meta["item"]
            # 5.获取详情压面解析到数据,并在items文件中配置属性
            director = response.xpath('/html/body/div[1]/div/div/div[1]/div[1]/div[2]/table/tbody/tr[1]/td[2]/a/text()').extract_first()
            details = response.xpath('/html/body/div[1]/div/div/div[1]/div[2]/div[2]/p/text()').extract_first()
            item["director"] = director
            item["details"] = details
    
            yield item

    items.py文件:

    import scrapy
    
    class FilmproItem(scrapy.Item):
        # define the fields for your item here like:
        # name = scrapy.Field()
        title = scrapy.Field() # 获取电影的标题
        grade = scrapy.Field() # 获取电影的评分
        director = scrapy.Field() # 获取详情页面中电影的导演
        details = scrapy.Field()# 获取详情页面中电影的简介

    pipelines.py管道文件

    class FilmproPipeline(object):
        fp = None
        def open_spider(self,spider):
            self.fp = open('./file.txt','w',encoding='utf-8')
            print("爬虫开始了!!!")
    
        def process_item(self, item, spider):
            self.fp.write(item['title'] + ":" + item['grade'] + ":" + item['director'] + item['details'] + "
    ")
            return item
    
        def close_spider(self,spider):
            self.fp.close()
            print("爬虫结束了!!!")

    settiung.py配置文件

    # 开启管道服务
    ITEM_PIPELINES = {
       'filmPro.pipelines.FilmproPipeline': 300,
    }

    总结:

      当使用scrapy进行数据爬取的时候,如果发现爬取的数据值没有在同一张页面中进行存储.
    则必须使用请求传参进行处理(持久化存储),在scrapy框架中,使用meta()进行请求传参

    三、如何提高scrapy的爬取效率
    增加并发:
        默认scrapy开启的并发线程为32个,可以适当进行增加。在settings配置文件中修改CONCURRENT_REQUESTS = 100值为100,并发设置成了为100。
    
    降低日志级别:
        在运行scrapy时,会有大量日志信息的输出,为了减少CPU的使用率。可以设置log输出信息为INFO或者ERROR即可。在配置文件中编写:LOG_LEVEL = ‘INFO’
    
    禁止cookie:
        如果不是真的需要cookie,则在scrapy爬取数据时可以进制cookie从而减少CPU的使用率,提升爬取效率。在配置文件中编写:COOKIES_ENABLED = False
    
    禁止重试:
        对失败的HTTP进行重新请求(重试)会减慢爬取速度,因此可以禁止重试。在配置文件中编写:RETRY_ENABLED = False
    
    减少下载超时:
        如果对一个非常慢的链接进行爬取,减少下载超时可以能让卡住的链接快速被放弃,从而提升效率。在配置文件中进行编写:DOWNLOAD_TIMEOUT = 10 超时时间为10s
    
    

     测试案例:

      爬取4k高清壁纸图片 http://pic.netbian.com/

    测试代码:

     爬虫文件:

    import scrapy
    from imagesPro.items import ImagesproItem
    
    
    class Image4kSpider(scrapy.Spider):
        name = 'image4K'
        # allowed_domains = ['www.xxx.com']
        start_urls = ['http://www.xxx.com/']
        url = "http://pic.netbian.com/index_%d.html"
        page = 1
    
        def parse(self, response):
            li_list = response.xpath('//div[@class="slist"]/ul/li')
            for li in li_list:
                # 获取解析到数据值,并在items文件中设置属性
                img_url ="http://pic.netbian.com" + li.xpath('./a/span/img/@src | ./a/img/@src').extract_first()
                img_name = li.xpath('./a/span/img/@alt | ./a/img/@alt').extract_first()
    
                #实例化item类型的对象,并将解析到的数据值储存到item对象中
                item = ImagesproItem()
                item["img_name"] = img_name
    
                # 使用yield获取详情页面,通过meta参数进行Request的数据传递(请求传参)
                yield scrapy.Request(url=img_url,callback=self.img_name,meta={"item":item})
    
            # 爬取多个分页页面
            if self.page <10:
                self.page += 1
                new_url = format(self.url%self.page)
                yield scrapy.Request(url=new_url,callback=self.parse)
    
        def img_name(self,response):
            # 通过response获取item对象
            item = response.meta["item"]
            item["img_data"] = response.body
    
            yield item

      items.py文件

    import scrapy
    
    class ImagesproItem(scrapy.Item):
        # define the fields for your item here like:
        img_name = scrapy.Field()
        img_data = scrapy.Field()
    pipelines.py(数据持久化存储)
    import os
    class ImagesproPipeline(object):
        def open_spider(self,spider):
            if not os.path.exists("images"):
                os.mkdir("./images")
        def process_item(self, item, spider):
            imgPath = "./images" + item["img_name"] + ".jpg"
            with open(imgPath,"wb") as fp:
                fp.write(item["img_data"])
                print(imgPath + "下载成功")
            return item
    
    

    setting.py文件配置

    ITEM_PIPELINES = {
       'imagesPro.pipelines.ImagesproPipeline': 300,
    }
    CONCURRENT_REQUESTS = 10  # 默认开启10个线程
    LOG_LEVEL = "ERROR"  # 默认打印错误信息日志,如果没有则不打印
    COOKIE_ENABLED = False  # 警用cookie
    RETRY_ENABLED = False #禁止重试
    DOWNLOAD_TIMEOUT = 10 # 设置超时时间
  • 相关阅读:
    爬虫实战篇(模拟登录)---我们以模拟去哪儿网为例
    requests库详解
    爬取拉钩网职位信息写入mongodb数据库(小白学爬虫--实战篇1)
    《Vue项目关于i18n双语切换》
    《Vue+Vuetify》
    《Vue项目的创建以及初始化(两种方法)》
    《关于Vue的涟漪点击》
    《Vue的父子组件传值》
    《vue 页面进出类似APP的滑动效果》
    《Vue里的路由拦截》
  • 原文地址:https://www.cnblogs.com/mwhylj/p/10267458.html
Copyright © 2020-2023  润新知