zoukankan      html  css  js  c++  java
  • 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'
    
  • 相关阅读:
    字符串 CSV解析 表格 逗号分隔值 通讯录 电话簿 MD
    Context Application 使用总结 MD
    RxJava RxPermissions 动态权限 简介 原理 案例 MD
    Luban 鲁班 图片压缩 MD
    FileProvider N 7.0 升级 安装APK 选择文件 拍照 临时权限 MD
    组件化 得到 DDComponent JIMU 模块 插件 MD
    gradlew 命令行 build 调试 构建错误 Manifest merger failed MD
    protobuf Protocol Buffers 简介 案例 MD
    ORM数据库框架 SQLite 常用数据库框架比较 MD
    [工具配置]requirejs 多页面,多入口js文件打包总结
  • 原文地址:https://www.cnblogs.com/zzsy/p/12694800.html
Copyright © 2011-2022 走看看