如何写一个爬虫 - 第三篇

这可能是一篇教你如何写爬虫的博客。

在第二篇中,我们介绍了 HTTP 最基本的动作:GET。这篇博客主要讲一下 HTTP 的其他几个动作。

本篇的内容主要来自 MDN

GET

HTTP GET 方法请求指定的资源,使用 GET 的请求应该只用于获取数据。

POST

HTTP POST 方法发送数据给服务器,请求主体的类型由 Content-Type 首部指定。

Content-Type 一般是以下几项之一:

  • application/x-www-form-urlencoded: 数据被编码成以 '&' 分隔的键-值对,同时以 '=' 分隔键和值。非字母或数字的字符会被 percent-encoding,这也就是为什么这种类型不支持二进制数据的原因 (应使用 multipart/form-data 代替)。
  • multipart/form-data
  • text/plain

(具体的分析在下一篇中讲解。)

application/x-www-form-urlencode

1
2
3
4
5
6
POST / HTTP/1.1
Host: foo.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13

say=Hi&to=Mom

multipart/form-data

1
2
3
4
5
6
7
8
9
10
11
12
POST /test.html HTTP/1.1 
Host: example.org
Content-Type: multipart/form-data;boundary="boundary"

--boundary
Content-Disposition: form-data; name="field1"

value1
--boundary
Content-Disposition: form-data; name="field2"; filename="example.txt"

value2

GET 与 POST 是最基本的两种请求方式,大部分的 web 服务器都会至少实现这两个方法。这两个也是最常用的方法。

PUT

请求方法 PUT 用于新增资源或者使用请求中的有效负载替换目标资源的表现形式。

1
2
3
4
5
6
PUT /new.html HTTP/1.1
Host: example.com
Content-type: text/html
Content-length: 16

<p>New File</p>

如果目标资源不存在,并且 PUT 方法成功创建了一份,那么源头服务器必须返回 201 (Created) 来通知客户端资源已创建。

1
2
HTTP/1.1 201 Created
Content-Location: /new.html

如果目标资源已经存在,并且依照请求中封装的表现形式成功进行了更新,那么,源头服务器必须返回 200 (OK) 或者 204 (No Content) 来表示请求的成功完成。

1
2
HTTP/1.1 204 No Content
Content-Location: /existing.html

DELETE

HTTP DELETE 请求方法用于删除指定的资源。

请求

1
DELETE /file.html HTTP/1.1

响应

如果 DELETE 方法成功执行,那么可能会有以下几种状态码:

  • 状态码 202 (Accepted) 表示请求的操作可能会成功执行,但是尚未开始执行。
  • 状态码 204 (No Content) 表示操作已执行,但是无进一步的相关信息。
  • 状态码 200 (OK) 表示操作已执行,并且响应中提供了相关状态的描述信息。
1
2
3
4
5
6
7
8
HTTP/1.1 200 OK 
Date: Wed, 21 Oct 2015 07:28:00 GMT

<html>
<body>
<h1>File deleted.</h1>
</body>
</html>

PATCH

在 HTTP 协议中,请求方法 PATCH 用于对资源进行部分修改。

请求

1
2
3
4
5
6
7
PATCH /file.txt HTTP/1.1 
Host: www.example.com
Content-Type: application/example
If-Match: "e0023aa4e"
Content-Length: 100

[description of changes]

响应

204 状态码表示这是一个操作成功的响应,因为响应中不带有消息主体。

1
2
3
HTTP/1.1 204 No Content
Content-Location: /file.txt
ETag: "e0023aa4f"

如果在 Restful API 中,以上 5 种请求方式分别对应(下面的表格来自 Wikipedia):

Operation SQL HTTP RESTful WS DDS
Create INSERT PUT / POST POST write
Read (Retrieve) SELECT GET GET read / take
Update (Modify) UPDATE PUT / POST / PATCH PUT write
Delete (Destroy) DELETE DELETE DELETE dispose

TRACE

HTTP TRACE 方法 实现沿通向目标资源的路径的消息环回(loop-back)测试 ,提供了一种实用的 debug 机制。

OPTIONS

HTTP 的 OPTIONS 方法 用于获取目的资源所支持的通信选项。客户端可以对特定的 URL 使用 OPTIONS 方法,也可以对整站(通过将 URL 设置为 "*")使用该方法。

检测服务器所支持的请求方法节

可以使用 OPTIONS 方法对服务器发起请求,以检测服务器支持哪些 HTTP 方法:

1
curl -X OPTIONS http://example.org -i

响应报文包含一个 Allow 首部字段,该字段的值表明了服务器支持的所有 HTTP 方法:

1
2
3
4
5
6
7
8
HTTP/1.1 200 OK
Allow: OPTIONS, GET, HEAD, POST
Cache-Control: max-age=604800
Date: Thu, 13 Oct 2016 11:45:00 GMT
Expires: Thu, 20 Oct 2016 11:45:00 GMT
Server: EOS (lax004/2813)
x-ec-custom-error: 1
Content-Length: 0

CORS 中的预检请求节

在 CORS 中,可以使用 OPTIONS 方法发起一个预检请求,以检测实际请求是否可以被服务器所接受。预检请求报文中的 Access-Control-Request-Method 首部字段告知服务器实际请求所使用的 HTTP 方法;Access-Control-Request-Headers 首部字段告知服务器实际请求所携带的自定义首部字段。服务器基于从预检请求获得的信息来判断,是否接受接下来的实际请求。

1
2
3
4
5
6
7
8
9
10
OPTIONS /resources/post-here/ HTTP/1.1 
Host: bar.other
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

服务器所返回的 Access-Control-Allow-Methods 首部字段将所有允许的请求方法告知客户端。该首部字段与 Allow 类似,但只能用于涉及到 CORS 的场景中。

1
2
3
4
5
6
7
8
9
10
11
12
13
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain

HTTP HEAD 方法 请求资源的首部信息, 并且这些首部与 HTTP GET 方法请求时返回的一致. 该请求方法的一个使用场景是在下载一个大文件前先获取其大小再决定是否要下载, 以此可以节约带宽资源。


以上 3 种一般用于确定服务器状态或者验证服务是否可用,其中的限制多是对浏览器而言的,爬虫大部分情况下不需要考虑这些。


CONNECT

在 HTTP 协议中,CONNECT 方法可以开启一个客户端与所请求资源之间的双向沟通的通道。它可以用来创建隧道(tunnel)。多用于与代理服务器的通信。

总结

以上就是 HTTP 的动作,为了写一个爬虫,这些是要有一些了解的。