唠唠叨叨之HTTP那些事

451 阅读11分钟

HTTP Messages

什么是 HTTP Messages?就是两个端点之间,透过 HTTP 协定交换数据的方式。

更简单的理解方式,想像我们在跟朋友聊天时,朋友会根据你所讲的话来回答你,或是你会根据朋友讲的话来回答他。

HTTP Request / Response Messages由以下组成:

  • Request line(用于 Request Message 的第一行 :叙述 Request 的 HTTP Method、目标(通常是 URL)、HTTP 版本,如:GET /example.gif HTTP/1.1
  • Status line(用于 Response Message 的第一行 :叙述 Response 的 HTTP 版本、状态码(HTTP Status)、Status Text,如:HTTP/1.1 404 Not Found,404 是 Status,Not Found 则是 Status Text。
  • Headers:定义操作参数,简单来说就是一种附加讯息。除了标准名称,也可以自己根据的需求来定义名称。因此可以在某些伺服器或浏览器上发现非标准的 Headers 名称。像我们常见的:Content-TypeUser-Agent等。更多的标准 Headers 可以在这边参考。
  • 空白行
  • Body:要传送或回应的 Data。

HTTP Method

GET 只用于取得资料。不会在 Message 的 Body 中传递资料,例:在某个网站要提取特定使用者资料时,通常只会在 URL query 的部分附上指定参数像是 user id 等。

POST 提交指定资源。会在 Message 的 Body 中传递资料,例:在某个网站要新增使用者时,就得在 Body 中附上伺服器规定需要的资料,像 user name、email 等栏位资料。

PUT 用来更新指定的资料(全部)。

PATCH 用来更新指定的资料(部份修改)。

DELETE 删除指定资源。

HTTP 状态码(HTTP Status)

通常只要看状态码的 Status 的类别与 Status Text 搭配 HTTP Response 的讯息基本上就能知道大概发生什么事了。

根据维基百科的定义,所有状态码被分为五類,状态码的第一個數字代表了回应的五种状态之一:

  • 1XX讯息:这一类型的状态码,代表请求已被接受,需要继续处理,标示客户应该等待伺服器采取进一步行动。由于 HTTP/1.0 并没有定义任何 1XX 状态码,所以除非在某些试验条件下,伺服器禁止向此类客户端传送 1XX 回应。这些状态码代表的回应都是资讯性的。
  • 2XX成功:代表请求已成功被伺服器接收、理解、并接受。
  • 3XX重新导向:这类状态码表示需要客户端采取进一步的操作才能完成请求。这些状态码通常用来重新导向。
  • 4XX客户端错误:这类的状态码代表了客户端看起来可能发生了错误,妨碍了伺服器的处理。例:404Not Found,表示 Request 的资源在伺服器上不存在、找不到。
  • 5XX服务器错误:表示服务器无法完成明显有效的请求,伺服器在处理请求的过程中有错误或者异常状态发生。

HTTP连线

HTTP连线时,每次连线都是独立的,意思是每次的连线都跟上一次的连线没有关系。如下图:

image.png

图片来源

  • 所以HTTP为了解决上述的问题,在 1.1 的版本中新增了持续连线的功能。不然每次连线时,TCP都得重新进行三方交握,是非常耗时的。

image.png

图片来源

然而HTTP还有一个致命缺点,它是使用明文传输。如果传递资料的过程中,被恶意拦截,资料便有机会被窥探、盗用,甚至伪造。进而产生风险。所以HTTPS就这么诞生拉!

HTTPS

  • HTTPS简单来说就是加密安全版的HTTP,过程使用SSL/TLS加密,来达成相对安全的资料传输。

TCP / IP 网路通讯模型

TCP / IP 是一个网路通讯模型,而现今网路的沟通,基本上都是依照 TCP / IP 的架构下去设计的。
那 TCP / IP 可以分为这四层。

  • 应用层(Application Layer) :所有和应用程式协同工作,利用网路交换应用程式资料的协定。如:HTTP、HTTPS、FTP 等。
  • 传输层(Transport Layer) :够解决端点之间的可靠性问题。如:TCP / UDP 篇所提到的「资料是否已经到达目的地?」和「资料是否按照正确的顺序到达?」这样的问题。而此层还包含了一个功能就是根据 Port 将资料送给对应的应用程式,比如说有个封包是要去 80 Port,它就会将此封包送至同样是 80 Port 在应用层中的应用程式。
  • 网路互连层(Internet Layer) :提供路由和寻址的功能,使两终端系统能够互连且决定最佳路径,并具有一定的拥塞控制和流量控制的能力。像是我们最常用到的 IP(IPv4、IPv6)。
  • 网路存取(连结)层(Network Access (Link) Layer) :主机物理连接的线路的方法和通信协议。像是实体 Port、Router 之类的。

TCP / IP 传输

了解 TCP / IP 的结构后,接下来将讲解它的资料流。
不啰嗦直接上图!

图 (1):
image.png

图 (2):

image.png

图片来源

从图 (1) 可以直接了解到,资料要传输时,是从应用层开始(Application Layer),一层一层由上往下叠加,如图 (2) 所示,当另外一端收到资料后再一层一层由下至上去解析

以上就是网际网路透过 TCP / IP 模型沟通的简单介绍!

三次交握

TCP 在发送资料前,发送端会与接收端进行三方交握的动作,来确认已经与接收端连上线。\

image.png 什么是三方交握

  1. 发送端接收端发送一个连接請求
  2. 接收端收到连接請求之后便会回传确认信号发送端
  3. 发送端收到接收端确认信号后,便会再发送讯息给接收端说:我确认你的确认信号了,我要发送资料给你喔!
  • 可靠的
    TCP 会为每个封包分配一个唯一的识别码与序号,让接收端在接收时,能够确保封包的完整性及顺序。当接收端收到封包后,如果顺序正确,会向发送端传送一个确认信号,以此确认接收端已经收到封包。反之,如果封包遗失或顺序错误,接收端则不会发送确认信号,而发送端需要重新传送。

UDP

  • UDP(User Datagram Protocol)就简单了,发送端送出资料后,接收端 那边封包正不正确,有没有收到"I don'tcarcare",总之收到的话就回我吧,大概是这样的感觉。

  • 大部分是应用在串流媒体的部分,对封包遗失容忍度较高的服务,像是:线上游戏、线上影音串流等。这也是为什么有时候网路连线品质不好的时候,会容易有掉帧(LAG)的情况。

Cookie 与 Session

不知道大家还记不记得,HTTP 有个特性就是每次连线都是独立的,与前次连线都毫无关系。以现实来比喻,就是每次跟同一个人讲话时都要重新自我介绍,明明前 1 分钟才自我介绍过 ==

所以!要怎么让 HTTP 解决这个问题呢!?那就是偷偷记下来拉~
那记下来之后,恩... 要放哪里呢?重点来了,会根据这些偷记下来的资讯的存放位置来给予称呼。
**存在 Client 端的,叫做Cookie
而 Server 端的,则叫Session

  • Cookie

    • 记录网站上的个人设定或是操作,像是:购物车,填到一半的资料等。这也是为什么有些网拍网站,明明没登入下次再访问同个网站时,却还能记着你购物车的内容或输入的资料。
      有些也会记录登入资讯(Session ID),这样就不用每次一直重复登录了!
    • 而 Cookie 是以明码的方式储存传送的,又是存在 Client 端,所以有被窜改的疑虑,所以通常不会放太重要的资料
    • 另外 Cookie 也是有时效性的,像是太久没访问某个网站,就需要再重新登入一次。
  • Session

    • 相对于 Cookie 而言安全性高,因位处存在 Server 端。主要记录 Server 上使用者的资讯,像是人数计数器、使用者的访问日期、登入资讯(登入日期、Session ID)等。
    • Session ID:就是使用者登入后,会产生一组 Session ID 。通常会存入 Cookie,当使用者再次访问时,Server 会去确认此 Session ID 使否存在或失效,来要求使用者是否需要重新登入。

所以有些资料是需要登入后才能获取的,就需要在爬虫程式中把 Cookie 的资讯填上,来维持登入状态。

从爬虫看 API / CGI

  • 介面
    假设有一个摇杆,摇杆上的每个按钮,各自有各自的功能对吧,那就是摇杆的介面,我们只需要怎么用不需要知道里面是怎么运作的。
  • 回到网页上,也就是说网页上那些查询、新增等等功能,那些就是界面(URL),而我们只需要知道喂给他们什么参数,不需要知道他们内部逻辑,就能得到预期的结果。
  • 所以当我们要爬虫时,就得先调查这些 URL 可以吃什么参数、怎么使用、有什么限制,再根据我们想要的结果丢相对应的参数给它。
  • Request 跟 Response,通常都是用 Json 来包装资料,资料格式依照设计也会有所不同

CGI

  • 一样也是介面
  • 有些网页会使用 CGI 技术来建构他们的网站,通常 Response 会是HTML。但不是一定,也有其他格式的 Response。
  • Request 的话,通常都是用 Form 来包装资料,这点要注意一下,不然是拿不到想要的 Response 的喔!这边也一样,资料格式依照设计也会有所不同

总之,不管网页提供什么介面,写爬虫程式前要好好调查一下那些介面要怎么使用喔!

URL (Uniform Resource Locator):

跟生活比较相关的,就是能用来表示 ISBN 国际书号,ISBN 通常都会在实体书条码那边看到。

例如:

  Clean Code: A Handbook of Agile Software Craftsmanship 1st
    ISBN 10 :9780132350884
  • 指的是网际网路上资源的位址,如同在网路上的门牌一般。像我们浏览器上的网址,它也是其中一种 URL。

  • 注意:并不是所有的 URL 都是 HTTP / HTTPS 开头的。

    • 例如:

          ftp://example.org/home
          telnet://192.168.0.100
      

URL 语法图:

image.png 根据图片,我们可以知道所谓的 URL ,是由 scheme、userinfo、host、port、path、query 及 fragment 组成,我们将这些元素,分成以下五个类别:

scheme:[//authority]path[?query][#fragment]
  1. scheme: 传送协定,例如:http、https、ftp、mailto、file、data 等,更多协定可至这边参考。以捷运站举例,这边是叙述你用什么方法到这捷运站。
  2. authority(optional): 存取资源需要的凭证资讯,在 URI 语法中此部分是可省略的。
  • 语法为:

    [userinfo@]host[:port]
    
  • userinfo(optional): 就是使用者名称及密码,格式为以下。以捷运站举例,这个捷运站普通人不能随便进去,你进去前要先验明身分。

    username:password
    
  • host: 资源点的 Domain name 或是 IP address。以捷运站举例,捷运站名就是 Domain name,捷运站地址就是 IP address。

  • port(optional): 当要访问某个资源点时,必须通过这个 port 来存取,若是走预设值,则可省略不写。像是我们的浏览器就没有显示 port,因为是走预设的 80 (http)或 443 port(https)。以捷运站举例,port 就像是捷运站的出入口一样。

  • 用法: 比方说我们要存取某个不公开的 ftp server,存取该资源需要输入凭证资讯

    ftp://bing:123@192.168.0.100:21/
    
    1. path: 路径(以「/」字元区别路径中的每一个目录名称)。

query(optional): 查询(以「?」字元为起点,每个参数以「&」隔开,再以「=」分开参数名称与资料,通常以 UTF-8 的 URL 编码,避开字元冲突的问题)。简单讲,就是传递参数。

-   例如:

    ```
    https://www.example.com/user?name=example
    ```

fragment(optional): 导向的锚点,例如:将网页的画面导向至指定的锚点位置。