ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 超文本传输协议 > 原文:[HTTP](https://www.textbook.ds100.org/ch/07/web_http.html) > > 校验:[Kitty Du](https://github.com/miaoxiaozui2017) > > 自豪地采用[谷歌翻译](https://translate.google.cn/) ```python # HIDDEN # Clear previously defined variables %reset -f # Set directory for data loading to work properly import os os.chdir(os.path.expanduser('~/notebooks/07')) ``` ## Http[](#Http) Http(AKA **H**yper**T**ext **T**transfer **P**rotocol)是一种 *请求-响应(request-response)* 协议,允许一台计算机通过 Internet 与另一台计算机对话。 ## 请求和响应[](#Requests-and-Responses) 互联网允许计算机互相发送文本,但不会对文本包含的内容施加任何限制。HTTP 定义了一台计算机(客户端client)和另一台计算机(服务器server)之间的文本通信结构。在这个协议中,客户机向服务器提交一个 *请求*,是一个特殊格式的文本消息。服务器将送回一个*响应*文本到客户端。 命令行工具`curl`为我们提供了发送 HTTP 请求的简单方法。在下面的输出中,以`>`开头的行表示请求中发送的文本;其余的行是服务器的响应。 ```bash $ curl -v https://httpbin.org/html ``` ``` > GET /html HTTP/1.1 > Host: httpbin.org > User-Agent: curl/7.55.1 > Accept: */* > < HTTP/1.1 200 OK < Connection: keep-alive < Server: meinheld/0.6.1 < Date: Wed, 11 Apr 2018 18:15:03 GMT < <html> <body> <h1>Herman Melville - Moby-Dick</h1> <p> Availing himself of the mild... </p> </body> </html> ``` 运行上面的`curl`命令会使客户机的计算机构造一条如下所示的文本消息: ``` GET /html HTTP/1.1 Host: httpbin.org User-Agent: curl/7.55.1 Accept: */* {blank_line} ``` 此消息遵循特定的格式:以`GET /html HTTP/1.1`开头,表示消息是对`/html`页的 HTTP`GET`请求。表单 HTTP 头后面的三行中的每一行,都是`curl`发送给服务器的可选信息。HTTP 头的格式为`{name}: {value}`。最后,消息结尾的空白行告诉服务器消息在三个头之后结束。注意,我们在上面的代码段中用`{blank_line}`标记了空白行;在实际的消息中`{blank_line}`用空白行替换。 然后,客户端的计算机使用 Internet 将此消息发送到`https://httpbin.org`Web 服务器。服务器处理请求,并发送以下响应: ``` HTTP/1.1 200 OK Connection: keep-alive Server: meinheld/0.6.1 Date: Wed, 11 Apr 2018 18:15:03 GMT {blank_line} ``` 响应的第一行说明请求已成功完成。下面的三行组成了 HTTP 响应头,这是服务器发送回客户机的可选信息。最后,消息结束时的空白行告诉客户端服务器已完成发送响应头,然后将发送响应体: ``` <html> <body> <h1>Herman Melville - Moby-Dick</h1> <p> Availing himself of the mild... </p> </body> </html> ``` 几乎每一个与互联网交互的应用程序都使用这个 HTTP 协议。例如,在您的 Web 浏览器中访问[https://httpbin.org/html](https://httpbin.org/html) 会发出与上面的`curl`命令相同的基本 HTTP 请求。您的浏览器没有像上面那样将响应显示为纯文本,而是识别出文本是一个 HTML 文档,并将相应地显示它。 实际上,我们不会以文本形式写出完整的 HTTP 请求。相反,我们使用像`curl`或 Python 库这样的工具来构造请求。 ### Python中[](#In-Python) Python **requests**库允许我们用 Python 发出 HTTP 请求。下面的代码发出的 HTTP 请求与运行`curl -v https://httpbin.org/html`相同。 ```python import requests url = "https://httpbin.org/html" response = requests.get(url) response ``` ``` <Response [200]> ``` ### 请求[](#The-Request) 让我们仔细看看我们提出的请求。我们可以使用`response`对象访问原始请求;我们在下面显示请求的 HTTP 头: ```python request = response.request for key in request.headers: # The headers in the response are stored as a dictionary. print(f'{key}: {request.headers[key]}') ``` ``` User-Agent: python-requests/2.12.4 Accept-Encoding: gzip, deflate Accept: */* Connection: keep-alive ``` 每个 HTTP 请求都有一个类型。在本例中,我们使用了一个从服务器检索信息的`GET`请求。 ```python request.method ``` ``` 'GET' ``` ### 响应[](#The-Response) 让我们检查一下从服务器收到的响应。首先,我们将打印响应的 HTTP 头。 ```python for key in response.headers: print(f'{key}: {response.headers[key]}') ``` ``` Connection: keep-alive Server: gunicorn/19.7.1 Date: Wed, 25 Apr 2018 18:32:51 GMT Content-Type: text/html; charset=utf-8 Content-Length: 3741 Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true X-Powered-By: Flask X-Processed-Time: 0 Via: 1.1 vegur ``` HTTP 响应包含一个状态码,是一个特殊的数字,表示请求是成功还是失败。状态码`200`表示请求成功。 ```python response.status_code ``` ``` 200 ``` 最后,我们显示响应内容的前 100 个字符(整个响应内容太长,无法在这里很好地显示)。 ```python response.text[:100] ``` ``` '<!DOCTYPE html>\n<html>\n <head>\n </head>\n <body>\n <h1>Herman Melville - Moby-Dick</h1>\n\n ' ``` ## 请求类型[](#Types-of-Requests) 我们上面的请求是一个`GET`Http 请求。有多种 HTTP 请求类型;最重要的两种是`GET`和`POST`请求。 ### GET 请求[](#GET-Requests) `GET`请求用于从服务器检索信息。由于您每次在地址栏中输入 URL 时您的 Web 浏览器都会发出`GET`请求,`GET`请求是最常见的 HTTP 请求类型。 `curl`默认使用`GET`请求,因此运行`curl https://www.google.com/`会向`https://www.google.com/`发出`GET`请求。 ### POST请求[](#POST-Request) `POST`请求用于将信息从客户端发送到服务器。例如,一些网页包含供用户填写的表单,例如登录表单。单击“提交”按钮后,大多数 Web 浏览器都会发出一个`POST`请求,将表单数据发送到服务器进行处理。 让我们来看一个将`'sam'`作为参数`'name'`发送的`POST`请求的例子。这个可以通过在命令行上运行 **`curl -d 'name=sam' https://httpbin.org/post`** 来完成。 请注意,这次我们的请求有一个主体(用`POST`请求的参数填充),响应的内容与之前的`GET`响应不同。 与 HTTP 头类似,以`POST`请求发送的数据使用键值格式。在 Python 中,我们可以通过使用`requests.post`并将字典作为参数传入来发出`POST`请求。 ```python post_response = requests.post("https://httpbin.org/post", data={'name': 'sam'}) post_response ``` ``` <Response [200]> ``` 服务器将用状态码响应,以表示`POST`请求是否成功完成。此外,服务器通常会发送一个响应主体来显示给客户机。 ```python post_response.status_code ``` ``` 200 ``` ```python post_response.text ``` ``` '{\n "args": {}, \n "data": "", \n "files": {}, \n "form": {\n "name": "sam"\n }, \n "headers": {\n "Accept": "*/*", \n "Accept-Encoding": "gzip, deflate", \n "Connection": "close", \n "Content-Length": "8", \n "Content-Type": "application/x-www-form-urlencoded", \n "Host": "httpbin.org", \n "User-Agent": "python-requests/2.12.4"\n }, \n "json": null, \n "origin": "136.152.143.72", \n "url": "https://httpbin.org/post"\n}\n' ``` ## 响应状态码类型[](#Types-of-Response-Status-Codes) 先前的 HTTP 响应的 HTTP 状态码为`200`。此状态码表示请求已成功完成。还有数百个其他的 HTTP 状态码。谢天谢地,它们被分为不同的类别,以便于记忆: * **100s**-信息:需要更多来自客户端或服务器的输入 _(例如 100 Continue(继续)、102 Processing(处理中))_ * **200S**-成功:客户端请求成功 _(例如 200 OK(成功),202 Accepted(已接受))_ * **300s**-重定向:请求的 URL 位于其他位置;可能需要用户的进一步操作 _(例如,300 Multiple Choices(多个选项),301 Moved Permanently(永久移动))_ * **400s**-客户端错误:客户端错误 _(例如 400 Bad Request(错误请求),403 Forbidden(禁止),404 Not Found(未找到))_ * **500s**-服务器错误:服务器端错误或服务器无法执行请求 _(例如,500 Internal Server Error(内部服务器错误),503 Service Unavailable(服务不可用))_ 我们可以看看其中一些错误的例子。 ```python # This page doesn't exist, so we get a 404 page not found error url = "https://www.youtube.com/404errorwow" errorResponse = requests.get(url) print(errorResponse) ``` ``` <Response [404]> ``` ```python # This specific page results in a 500 server error url = "https://httpstat.us/500" serverResponse = requests.get(url) print(serverResponse) ``` ``` <Response [500]> ``` ## 摘要[](#Summary) 我们介绍了 HTTP 协议,这是使用 Web 的应用程序的基本通信方法。尽管协议指定了一种特定的文本格式,但我们通常使用其他工具来为我们发出 HTTP 请求,例如命令行工具`curl`和 Python 库`requests`。