• scrapy框架五大核心组件


    爬虫五大核心组件

     组件的作用:
            引擎(Scrapy)
                用来处理整个系统的数据流处理, 触发事务(框架核心)
            调度器(Scheduler)
                用来接受引擎发过来的请求, 压入队列中, 并在引擎再次请求的时候返回. 可以想像成一个URL(抓取网页的网址或者说是链接)的优先队列, 由它来决定下一个要抓取的网址是什么, 同时去除重复的网址
            下载器(Downloader)
                用于下载网页内容, 并将网页内容返回给蜘蛛(Scrapy下载器是建立在twisted这个高效的异步模型上的)
            爬虫(Spiders)
                爬虫是主要干活的, 用于从特定的网页中提取自己需要的信息, 即所谓的实体(Item)。用户也可以从中提取出链接,让Scrapy继续抓取下一个页面
            项目管道(Pipeline)
                负责处理爬虫从网页中抽取的实体,主要的功能是持久化实体、验证实体的有效性、清除不需要的信息。当页面被爬虫解析后,将被发送到项目管道,并经过几个特定的次序处理数据。
    
    

    请求传参的实现深度爬取

    请求传参实现的深度爬取
    - 深度爬取:爬取的数据没有在同一张页面中(首页数据+详情页数据)
    - 在scrapy中如果没有请求传参我们是无法持久化存储数据
    - 实现方式:
        - scrapy.Request(url,callback,meta)
            - meta是一个字典,可以将meta传递给callback
        - callback取出meta:
            - response.meta
    

    代码实现:

    # -*- coding: utf-8 -*-
    import scrapy
    
    from movie.items import MovieItem
    class MovieTestSpider(scrapy.Spider):
        name = 'movie_test'
        # allowed_domains = ['www.xxxxx.com']
        start_urls = ['https://www.4567kan.com/index.php/vod/show/id/5.html']
    
        url ="https://www.4567kan.com/index.php/vod/show/id/5/page/{}.html"
        page = 2
        def parse(self, response):
            li_list = response.xpath("/html/body/div[1]/div/div/div/div[2]/ul/li")
            for li in li_list:
                titile = li.xpath("./div/a/@title").extract_first()
                src = "https://www.4567kan.com"+li.xpath("./div/a/@href").extract_first()
    
                item = MovieItem()
                item["title"] = titile
    
    
                yield scrapy.Request(url = src,callback=self.parse_movie,meta={"item":item})
    
            if self.page<5:
                new_url = self.url.format(self.page)
                self.page+=1
                yield scrapy.Request(url = new_url,callback=self.parse)
    
    
    
    
        def parse_movie(self,response):
            print(response)
            item = response.meta["item"]
            desc = response.xpath('/html/body/div[1]/div/div/div/div[2]/p[5]/span[2]/text()').extract_first()
            item["desc"] = desc
            yield item
    
    
    

    中间件

    • 作用:批量拦截请求和响应

    • 爬虫中间件(暂时未讲)

    • 下载中间件(推荐)

      • 拦截请求:
        • 篡改请求Url
        • 伪装请求头信息
          • UA
          • cookie
        • 设置请求代理(重点)
      • 拦截响应
        • 篡改响应数据
      • 代理操作必须使用中间件才可以实现
        • process_exception:
          • request.meta["proxy"] = "http:// ip:port"

    middlewares.py代码

    class MiddleproDownloaderMiddleware(object):
    	#拦截所有的请求(正常和异常的都算上)
    	def process_request(self,request,spider):
    		print("process_request()")
    		request.headers["User-Agent"] = "xxxx"
    		request.headers["Cookie"] = "xxxxx"  #但是平常我们不会这么做,因为settings中有cookie配置,scrapy每次请求会带这cook 
    		return None  #或者request
    		
    	#拦截所有响应的对象
    	#参数:response拦截到的响应对象,request响应对象对应的请求对象
    	def process_exception(self,request,response,spider):
    		print("process_response()")
    		return response
    		
    	#拦截异常的请求
    	#参数:request就是拦截到的发生异常的请求
    	#作用:想要将异常的请求进行修正,将其变成正常的请求,然后对其重新发送
    	def process_exception(self.request,exception,spider):
    		#请求的ip被禁掉,该请求就会变成一个异常的请求
    		#这里的meta跟请求传参一样。都是Request
    		request.meta["proxy"] = "http://ip:port" #设置代理
    		print("process_exception()")
    		return request #将异常的请求修正后将其重新发送
    		
    

    在settings中

    打开这个配置,每次请求都会带这cookie,不需要咱们去添加!

    下载图片的爬取

    大文件下载:大文件数据是在管道中请求到的

    • 下属管道类是scrapy封装好的我们直接用即可:

    • from scrapy.pipelines.images import ImagesPipeline #提供了数据下载功能

      重写该管道类的三个方法:

      • get_media_requests
        • 对图片地址发起请求
      • file_path
        • 返回图片名称即可
      • item_copleted
        • 返回item,将其返回给下一个即将被执行的管道类
      • 在配置文件中添加:
        • IMAGES_STORE = 'dirName'

    img.py

    import scrapy
    
    from imgPro.items import ImgproItem
    class ImgSpider(scrapy.Spider):
        name = 'img'
        # allowed_domains = ['www.xxx.com']
        start_urls = ['http://www.521609.com/daxuexiaohua/']
    
        def parse(self, response):
            #解析图片地址和图片名称
            li_list = response.xpath('//*[@id="content"]/div[2]/div[2]/ul/li')
            for li in li_list:
                img_src = 'http://www.521609.com'+li.xpath('./a[1]/img/@src').extract_first()
                img_name = li.xpath('./a[1]/img/@alt').extract_first()+'.jpg'
    
                item = ImgproItem()
                item['name'] = img_name
                item['src'] = img_src
    
                yield item
    

    items.py

    import scrapy
    
    
    class ImgproItem(scrapy.Item):
        # define the fields for your item here like:
        name = scrapy.Field()
        src = scrapy.Field()
    
    

    pipelines.py

    #该默认管道无法帮助我们请求图片数据,因此该管道我们就不用
    # class ImgproPipeline(object):
    #     def process_item(self, item, spider):
    #         return item
    
    #管道需要接受item中的图片地址和名称,然后再管道中请求到图片的数据对其进行持久化存储
    from scrapy.pipelines.images import ImagesPipeline #提供了数据下载功能
    from scrapy.pipelines.media import MediaPipeline
    from scrapy.pipelines.files import FilesPipeline
    import scrapy
    class ImgsPipiLine(ImagesPipeline):
        #根据图片地址发起请求
        def get_media_requests(self, item, info):
            # print(item)
            yield scrapy.Request(url=item['src'],meta={'item':item})
        #返回图片名称即可
        def file_path(self, request, response=None, info=None):
            #通过request获取meta
            item = request.meta['item']
            filePath = item['name']
            return filePath #只需要返回图片名称
        #将item传递给下一个即将被执行的管道类
        def item_completed(self, results, item, info):
            return item
    

    settings.py

    ITEM_PIPELINES = {
       'imgPro.pipelines.ImgsPipiLine': 300,
    }
    IMAGES_STORE = './imgLibs'
    
  • 相关阅读:
    linux查看电脑温度
    sshd_config详解
    Python Matplotlib包中文显示异常解决方法
    "打开jupyter notebook后找不到安装Anaconda的环境"的解决方法
    [7]力扣每日一题
    UML复习回忆
    [6]力扣每日一题
    [4]力扣每日一题
    [3]力扣每日一题
    mybatis 动态创建表、主键、索引、注释
  • 原文地址:https://www.cnblogs.com/zzsy/p/12694800.html
Copyright © 2020-2023  润新知