003.Python爬虫系列_HTTP&HTTPS协议

无奋斗不青春

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈
入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈
虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈
PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈
Oracle数据库教程:👉👉 Oracle数据库文章合集 👈👈
优 质 资 源 下 载 :👉👉 资源下载合集 👈👈
优 质 教 程 推 荐:👉👉 Python爬虫从入门到入狱系列 合集👈👈

分隔线
在这里插入图片描述

HTTP协议

概念

  • 协议就是两个计算机之间为了能够流畅的进行沟通而设置的一个君子协定
  • 常见的协议有TCP/IP,SOAP协议, HTTP协议, SMTP协议等等…
  • HTTP:超文本传输协议(HyperText Transfer Protocol),是一个基于请求与响应模式的、无状态的、应用层的协议
    • 超文本:包含文本、图片、音频、视频等多媒体资源
    • 请求:客户端要告诉服务器我需要什么
    • 响应:服务器根据客户端的需要,发送相应的东西给客户端
    • 无状态:每一次请求与响应完成之后,就结束。并不会记录任何状态
  • 作用:制定了应用程序间数据传输的规范

HTTP两大块

  • HTTP协议把一条消息分为三大块内容,无论是请求还是响应都是三块内容

  • 请求:

    请求行 -> 请求方式(get/post) 请求url地址 协议
    请求头 -> 放一些服务器要使用的附加信息(cookie验证,token,各种各样的反爬信息)
    
    请求体 -> 一般放一些请求参数
    
  • 响应:

    状态行 -> 协议 状态码 
    响应头 -> 放一些客户端要使用的一些附加信息(cookie验证,token,各种各样的反爬信息)
    
    响应体 -> 服务器返回的真正客户端要用的内容(HTML,json)
  • 在后面我们写爬虫的时候要格外注意请求头和响应头.这两个地方一般都隐含着一些比较重要的内容

  • 注意:浏览器实际上把HTTP的请求和响应的内容进行重组了,显示成我们更容易阅读的效果

    • 在这里插入图片描述

    • 在这里插入图片描述

    • 在这里插入图片描述

  • 请求头中最常见的一些重要内容(爬虫需要):

    User-Agent   # 请求载体的身份标识(用什么设备发送的请求)
    Referer      # 防盗链(这次请求是从哪个页面来的? 反爬会用到)
    cookie       # 本地字符串数据信息(用户登录信息,反爬的token)
    
  • 响应头中一些重要的内容:

    cookie      # 本地字符串数据信息(用户登录信息,反爬的token)
    各种神奇的莫名其妙的字符串(这个需要经验了,一般都是token字样,防止各种攻击和反爬)
    
  • 请求方式:

    • HTTP中有9种请求方式,在爬虫生涯中最常见的就是GET请求和POST请求
      GET         # 显示提交,在网址栏能看到参数
                  # 在浏览器直接输入网址进入网站,全是GET
                  # 超链接一般都是GET请求
      POST        # 隐示提交,提交的数据一般在地址栏看不见
                  # 表单(登录、注册、密码)类型的基本都是POST请求
      
      # 请求方式在:Network——Headers——General中查看
      
  • HTTP请求和HTTP响应

    • 请求和响应是成对出现的,有请求有响应
    • 所以,我们之前所说的客户端和web服务器的交互,本质就是:客户端想服务器发送HTTP请求,服务器给客户端HTTP响应
      • 在这里插入图片描述
  • 协议要求具体数据格式

  • 谷歌浏览器——打开网页——F12——Network

  • 请求头

    • 在这里插入图片描述
  • 响应头+响应体

    • 在这里插入图片描述

    • 在这里插入图片描述

  • 客户端向服务器发送请求,得到某些数据

    • 应用层遵循HTTP协议,将相关数据准备成请求头相关格式,再发送给服务器
    • 服务器再将相关数据,按照响应头和响应体的格式,返回给客户端
HTTP请求
HTTP请求组成部分
  • 图示

    • 在这里插入图片描述
  • 组成

    • 请求行:请求方法 URL 协议版本
    • 请求头部:
    • 请求数据:一般POST请求时才会有请求数据,GET请求没有请求数据
请求行
  • 组成部分
    • 请求行:请求方法 URL 协议版本
    GET /index.html HTTP/1.1
    
    # GET               # 请求方法
    # /index.html       # URL
    # HTTP/1.1          # 协议版本
    # 三部分内容,中间以空格进行分割
    
  • 请求方法
    • 8种请求类型(请求方法)
      ★ GET         # 请求指定的页面信息,并返回实体主体
      ★ POST        # 向指定资源提交数据进行处理请求
         HEAD        # 请求指定的页面信息,并返回头部信息
         PUT         # 向指定资源位置上传其最新内容
         DELETE      # 请求服务器删除指定资源
         OPTIONS     # 返回服务器针对特定资源所支持的HTTP请求方法
                     # 也可以利用向web服务器发送"*"的请求来测试服务器
         TRACE       # 回显服务器收到的请求,主要用于测试或诊断
                     # 让web服务器端将之前的请求通信还给客户端
         CONNECT     # 在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信
                     # 主要使用SSL(安全套接层)和TLS(传输层安全)协议吧通信内容加密后经网络隧道传输
      
    • 常用类型(GET和POST)
      • 共同点:都能将数据传递给服务器,但使用目的不同
        • GET主要目的是:将一些“条件、要求”传递给服务器,服务器返回满足条件结果
        • POST主要目的是:单纯的是将数据传递到服务器端(上传图片、账号和密码…)
      • 不同点
        • 参数传递方式不一样
          • GET:将参数直接拼接在URL地址后面。http://www.xxx.com?key1=value1&key2=value2
            • 特征:参数类型只能是字符串,不能是二进制流
          • POST:将参数单独存放在请求体中,不会拼接在URL后面。
            • 特征:参数类型可以是字符串,也可以是二进制流
        • 浏览器相关
          GETPOST
          缓存不会
          书签保存可以不可以
          历史记录没有
          刷新页面无反应重新发送请求,提交表单
      • 注意
        • 不管是GET还是POST请求,传输铭文数据都不安全。敏感性数据需要加密
        • GET一般用于请求数据,POST一般用于提交数据,但不绝对,爬取网页时,一定要看清楚别人写的是什么请求
    • 关于参数
      • get请求的参数在url上面
      • 抓包的时候,参数体现在
        Network —— Payload —— Query String Parameters
        
      • post请求的参数在请求体中,根据Content-Type的不同,给出不同的数据格式
        # 格式一
        Network —— Payload —— form data
        # 此时:Content-Type的值是 application/X-WWW-form-Urlencoded; charset=UTF-8
        # 数据格式是:year=2024&MethodName=BoxOffice_GetYearInfoData
        
        # 格式二
        Network —— Payload —— request payload
        # 此时:Content-Type的值就不一定是什么玩意了,常规情况是json
        # request payload里面的东西是直接被挂载在请求体上的
        
        
      • post请求也是有url的,在url上面也可能会挂载数据,Query String Parameters也可能会出现
  • URL地址
    • 请求资源的路径(请求服务器上哪个web资源)
    • 翻译过来就是:统一资源定位符,负责定位互联网上的一个资源
    • url组成部分:协议://域名:端口号/虚拟目录/.../资源?参数1=值1&参数2=值2...
      • http协议的默认端口号是:80
      • https协议的默认端口号是:443
  • 协议版本
    • HTTP/0.9:只有基本的文本GET功能
    • HTTP/1.0:完善的请求/响应模型,并将协议补充完整,定义了三种请求方法:GET、POST和HEAD
    • HTTP/1.1:(常用)在1.0的基础上进行更新,新增了五中请求方法:OPTIONS、PUT、DELETE、TRACE和CONNECT
    • HTTP/2.0:(未普及)请求/响应首部的定义基本没有改变,只是所有首部键必须全部小写,而且请求行要独立为:method、:scheme、:host、:path这些键值对
请求头部
  • 展现形式
    • 键值对形式
      • key1: value1
      • key2: value2
  • 常见请求头
    Referer                             # 浏览器告诉服务器,当前请求来自何处。如果是直接访问,则不会有这个请求头。常用于:防盗链
    User-Agent                          # 浏览器告诉服务器,客户端相关信息。
    Cookie                              # 用于存放浏览器缓存的cookie信息。HTTP请求是无状态的
    Host                                # 请求的服务器主机名和端口号。一般从URL地址中解析
    Connection                          # 客户端与服务连接类型
                                        # 1、客户端发送请求Connection:keep-alive,HTTP/1.1使用keep-alive为默认值
                                        # 2、服务器收到该请求后:
                                            # 支  持,响应时包含Connection:keep-alive,不关闭本次连接
                                            # 不支持,响应时包含Connection:close,关闭本次连接
                                        # 3、客户端如果收到的响应中包含Connection:keep-alive,同一个连接发送下一个请求,知道乙方主动关闭连接
                                        # 好处:重用连接,减少资源消耗,缩短响应时间
                                        # 影响:当Connection为keep-alive时,爬虫发送多个请求,导致占用服务器太多连接,部分网站会因此而取消返回数据
                                        # 解决:此时我们可以将Connection设置为close
    Upgrade-Insecure-Requests           # 告诉服务器可以升级不安全请求为安全请求
                                        # 如果服务器支持,就会可以使用重定向把http请求转换成https请求
    Accept                              # 告诉服务端,客户端浏览器可支持的MIME类型(文件类型的一种描述方式)
                                            # text/html         html文件
                                            # text/css          css文件
                                            # text/javascript   js文件
                                            # image/*           所有图片文件
                                        # 常见取值
                                            # */*               什么格式都能接收
                                            # text/html         希望接收html文本
                                            # image/*           接收所有图片资源
                                            # image/png         接收png格式的图片资源
                                            # application/xhtml+xml     接收xhtml和xml格式文本
                                        # q=0.9 ... q=0.8 表示接收权重,权重高的优先接收
    Accept-Encoding                     # 告诉服务端,客户端支持的编码格式
    Accept-Language                     # 告诉服务端,客户端支持的语言zh-CN:中文,en:英文,q:权重
    If-Modified-Since                   # 浏览器告诉服务端,文件缓存的最后变更时间,用于与服务器最新更新时间进行对比
                                        # 对比两个时间,如果一致则不发送请求,直接从缓存里面加载,否则发送请求,加载新数据
    If-None-Match                       # 客户端根据缓存文件数据内容计算出来的一串标识码,与服务端响应头里面的ETag值进行对比
                                        # ETag值:服务端返回根据服务端文件内容计算出来的标识码
                                        # 用于控制是否允许在对应的内容违背修改的情况下返回304未修改
                                        # If-Modified-Since和If-None-Match的主要作用:
                                        # 一个对比缓存与服务端文件的时间,一个对比两者根据文件内容计算出来的标识码
                                        # 在保证客户端请求数据是最新数据的前提之下,尽可能的从缓存获取,从而减少请求次数(减少服务器压力,提升用户体验)
    Content-Length                      # 请求体的长度
    Content-Type                        # 如果是POST请求,会使用这个key来表示请求体内容的类型
    									# 1. application/x-www-form-urlencoded; charset=UTF-8
                                            # 采用form表达的形式传递数据:key1=value1&key2=value2...
                                            # year=2024&MethodName=BoxOffice_GetYearInfoData
                                        # 2. application/json;charset=UTF-8
                                            # 采用json的形式传递数据:{key1:valye1,key2:value2...}
                                            # {year:2024, MethodName:BoxOffice_GetYearInfoData}
                                        # 3. Content-Type=Text/XML;charset=gb2312
                                            # 纯文本的xml类型的数据,字符编码是gb2312
    X-Requested-With:XMLHttpRequest     # 并不是浏览器自带的,是jquery库自动添加的
                                        # XMLHttpRequest表示该请求由Javascript中的XHR发送的(部分网站会进行验证)
    .
    .
    .
    .
    
  • 爬虫常用请求头
    User-Agent                          # 记录者用户的社保信息(该值直接从浏览器复制,不要手动填写)
    Referer 							# 防盗链,表示当前请求必须得是从指定页面发送起的,否则不给资源
    Cookie  
    Connection                          # 客户端与服务连接是否保存高可用状态
                                        # keep-alive保持高可用状态,会影响到爬虫发送大量请求时保持了太多高可用状态,被服务器干掉
                                        # 解决:一般将keep-alive关闭,改为close
    Accept                              # 告诉服务端,应该返回给客户端浏览器数据的类型(该值直接从浏览器复制,不要手动填写)
    Accept-Encoding                     # 告诉服务端,数据在传输时,用何种方式进行压缩。常规是gzip、br...
                                        # 如果请求之后拿到一堆字节,但是浏览器拿到的是html...很有可能是遇到了br...
                                        # 解决:在Accept-Encoding的值中删除br即可(或者安装第三方库 pip install brotli)
    Accept-Language                     # 告诉服务端,客户端支持的语言zh-CN:中文,en:英文,q:权重
    Content-Length                      # 传递数据的长度
    Content-Type                        # 传递给服务器的数据格式
                                        # 1. application/x-www-form-urlencoded; charset=UTF-8
                                            # 采用form表达的形式传递数据:key1=value1&key2=value2...
                                            # year=2024&MethodName=BoxOffice_GetYearInfoData
                                        # 2. application/json;charset=UTF-8
                                            # 采用json的形式传递数据:{key1:valye1,key2:value2...}
                                            # {year:2024, MethodName:BoxOffice_GetYearInfoData}
    X-Requested-With:XMLHttpRequest     # 并不是浏览器自带的,是jquery库自动添加的
                                        # XMLHttpRequest表示该请求由Javascript中的XHR发送的(部分网站会进行验证)
    
请求体
  • 请求数据:一般POST请求时才会有请求数据,GET请求没有请求数据
  • 请求头里面的数据,根据请求方式的不同,content-type的不同,数据也会不同
HTTP响应
HTTP响应组成部分
  • 图示

    • 在这里插入图片描述
  • 组成

    • 请求行:协议版本 状态码 描述
    • 请求头部:
    • 请求数据:
响应行
  • 组成部分

    • 响应行:协议版本 状态码 描述
  • 协议版本

    • HTTP/0.9:只有基本的文本GET功能
    • HTTP/1.0:完善的请求/响应模型,并将协议补充完整,定义了三种请求方法:GET、POST和HEAD
    • HTTP/1.1:(常用)在1.0的基础上进行更新,新增了五中请求方法:OPTIONS、PUT、DELETE、TRACE和CONNECT
    • HTTP/2.0:(未普及)请求/响应首部的定义基本没有改变,只是所有首部键必须全部小写,而且请求行要独立为:method、:scheme、:host、:path这些键值对
  • 状态码分类

    • 1xx(信息性状态码):表示接收的请求正在处理
    • 2xx(成功状态码):表示请求正常处理完毕
    • 3xx(重定向状态码):需要后续操作才能完成这一请求
    • 4xx(客户端错误状态码):表示请求包含语法错误或无法完成
    • 5xx(服务器错误状态码):服务器在处理请求的过程中发生了错误
  • 状态码描述

    状态码状态码英文名称中文描述
    100Continue继续。客户端应继续其请求
    101Switching Protocols切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议
    200OK请求成功。一般用于GET与POST请求
    201Created已创建。成功请求并创建了新的资源
    202Accepted已接受。已经接受请求,但未处理完成
    203Non-Authoritative Information非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本
    204No Content无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
    205Reset Content重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
    206Partial Content部分内容。服务器成功处理了部分GET请求
    300Multiple Choices多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择
    301Moved Permanently永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替
    302Found临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI
    303See Other查看其它地址。与301类似。使用GET和POST请求查看
    304Not Modified未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
    305Use Proxy使用代理。所请求的资源必须通过代理访问
    306Unused已经被废弃的HTTP状态码
    307Temporary Redirect临时重定向。与302类似。使用GET请求重定向
    400Bad Request客户端请求的语法错误,服务器无法理解
    401Unauthorized请求要求用户的身份认证
    402Payment Required保留,将来使用
    403Forbidden服务器理解请求客户端的请求,但是拒绝执行此请求
    404Not Found服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
    405Method Not Allowed客户端请求中的方法被禁止
    406Not Acceptable服务器无法根据客户端请求的内容特性完成请求
    407Proxy Authentication Required请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权
    408Request Time-out服务器等待客户端发送的请求时间过长,超时
    409Conflict服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突
    410Gone客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置
    411Length Required服务器无法处理客户端发送的不带Content-Length的请求信息
    412Precondition Failed客户端请求信息的先决条件错误
    413Request Entity Too Large由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息
    414Request-URI Too Large请求的URI过长(URI通常为网址),服务器无法处理
    415Unsupported Media Type服务器无法处理请求附带的媒体格式
    416Requested range not satisfiable客户端请求的范围无效
    417Expectation Failed(预期失败)服务器无法满足请求头中 Expect 字段指定的预期行为。
    418I'm a teapot状态码 418 实际上是一个愚人节玩笑。它在 RFC 2324 中定义,该 RFC 是一个关于超文本咖啡壶控制协议(HTCPCP)的笑话文件。在这个笑话中,418 状态码是作为一个玩笑加入到 HTTP 协议中的。
    500Internal Server Error服务器内部错误,无法完成请求
    501Not Implemented服务器不支持请求的功能,无法完成请求
    502Bad Gateway作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应
    503Service Unavailable由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中
    504Gateway Time-out充当网关或代理的服务器,未及时从远端服务器获取请求
    505HTTP Version not supported服务器不支持请求的HTTP协议的版本,无法完成处理
响应头
  • 服务端将信息以键值对的形式返回给客户端
  • 常见响应头
    ★ Content-Type                    # 响应体正文的类型(MIME类型)
    ★ Content-length                  # 响应正文的长度
    ★ Set-Cookie                      # 服务器想浏览器写入cookie
    
    Location                            # 指定响应的路径,需要与状态码302配合使用,完成跳转
    Server                              # 服务器名称
    Last-Modified                       # 服务器告诉客户端浏览器,文件的以后修改时间
    Cache-Control                       # 缓存控制
    Content-Disposition                 # 通过浏览器以下载方式解析正文
    Content-Encoding                    # 服务器使用的压缩格式
    Refresh                             # 定时刷新
    
  • 常用响应头信息
    Location                            # 浏览器重定向到一个新的地址
    cookie                              # 记录服务器和浏览器直接的状态
    
响应数据
  • 响应体
    • 响应体是服务器回写给客户端的正文数据。要解析这一部分数据,还要结合响应头里面的Content-Type进行解析

HTTP协议弊端

  • 1、通信使用铭文,不对数据进行加密,内容容易被窃听
  • 2、无法确定报文完整性,内容容易被篡改
  • 3、不验证通信方身份,容易伪装


HTTPS协议

概念

  • 与SSL(安全套接层)组合使用的HTTP被称为HTTPS(HTTP Secure 超文本传输安全协议)
  • HTTPS并不是一个新的协议,依然是属于HTTP协议,只不过是在HTTP协议的基础上进行了加密
  • HTTP + 加密 + 认证 = HTTPS
  • 图示
    • 在这里插入图片描述

数据加密的演化

  • 0、加密算法

    • 对称加密:加密和解密都是使用的同一个秘钥
    • 非对称加密:加密和解密使用的秘钥不相同,性能较低,但安全性超强
    • 哈希算法:将任意长度的信息转换成较短的固定长度的值,通常起长度要比信息小得多,且算法不可逆。
    • 数字签名:签名就是在信息的后面加上一段内容(信息经过hash后的值),可以证明信息没有被修改过
  • 1、原始的HTTP访问流程

    • HTTP请求
      • 在这里插入图片描述

      • 客户端向服务端发送hello,服务端响应hello,说明线路是通的。然后传输真正的内容

    • 弊端
      • 在这里插入图片描述

      • 由于数据传输过程是明文,所以很容易被中间的第三方获取到数据,并对数据进行篡改

  • 2、解决方案-1

    • 使用对称秘钥对数据进行加密
    • 弊端:秘钥也有可能被泄露
    • 在这里插入图片描述
  • 3、解决方案-2

    • 使用非对称加密对数据进行加密

    • 弊端:公钥公开,那么第三方也可以得到公钥进行解密服务器数据

    • 非对称加密效率低,但安全性好

    • 在这里插入图片描述

    • 客户端发送的请求内容,通过公钥进行加密,需要私钥才能解密

    • 第三方获取到了公钥,也无法对客户端发送的请求内容进行解密,无法查看到请求内容

    • 第三方可以通过公钥,对服务器响应内容进行解密查看,但是不能修改

    • 因为第三方没有私钥,无法对修改后的数据进行加密发送给客户端

    • 但是

    • 如果一开始,客户端拿到的公钥就是第三方的,第三方通过自己的私钥,可以解密客户端的请求内容

    • 然后第三方再通过服务器的公钥对请求内容进行加密,发送给服务器。服务器根据请求,响应数据

    • 第三方通过服务器的公钥,对服务器的加密响应数据进行解密,对响应数据进行篡改之后,通过自己的私钥进行加密

    • 客户端接收到第三方篡改后的加密数据,使用第三方的公钥进行解密(可以正常解密数据,无法发现数据被篡改)

    • 在这里插入图片描述

  • 4、解决方案-3

    • 使用安全性高的非对称加密来加密并传递堆成秘钥(混合)
      • 在这里插入图片描述
  • 弊端问题

    • 客户端的公钥从哪里来?
      • 1、客户端请求时,服务器指定网址下载(可以伪造)
      • 2、客户端请求时,服务器直接响应公钥(无法确认服务器身份,公钥可能是第三方公司给的公钥)
    • 如何确认服务器身份?
      • 1、使用SSL证书,需要申购
        • SSL证书内容:
          • a、正是的发布机构CA
          • b、证书的有效期
          • c、公钥
          • d、证书所有者
          • e、签名
          • f、…
  • 最终流程

    • 在这里插入图片描述
  • 校验流程

    • 1.验证证书所有者、有效期等信息
    • 2.通过系统内置的信任CA和证书CA进行比对
    • 3.取出内置的信任CA公钥解密签名
    • 4.使用相同的hash算法计算出证书hash值,校验签名
    • 5.没问题则取出服务器证书公钥
    • 在这里插入图片描述
  • 查看内置受信任证书CA列表

  • 谷歌浏览器—— 右侧 —— 设置 —— 高级设置 —— HTTPS/SSL —— 管理证书

  • 在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

失心疯_2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值