# 超文本传输协议
> 原文:[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`。
- 一、数据科学的生命周期
- 二、数据生成
- 三、处理表格数据
- 四、数据清理
- 五、探索性数据分析
- 六、数据可视化
- Web 技术
- 超文本传输协议
- 处理文本
- python 字符串方法
- 正则表达式
- regex 和 python
- 关系数据库和 SQL
- 关系模型
- SQL
- SQL 连接
- 建模与估计
- 模型
- 损失函数
- 绝对损失和 Huber 损失
- 梯度下降与数值优化
- 使用程序最小化损失
- 梯度下降
- 凸性
- 随机梯度下降法
- 概率与泛化
- 随机变量
- 期望和方差
- 风险
- 线性模型
- 预测小费金额
- 用梯度下降拟合线性模型
- 多元线性回归
- 最小二乘-几何透视
- 线性回归案例研究
- 特征工程
- 沃尔玛数据集
- 预测冰淇淋评级
- 偏方差权衡
- 风险和损失最小化
- 模型偏差和方差
- 交叉验证
- 正规化
- 正则化直觉
- L2 正则化:岭回归
- L1 正则化:LASSO 回归
- 分类
- 概率回归
- Logistic 模型
- Logistic 模型的损失函数
- 使用逻辑回归
- 经验概率分布的近似
- 拟合 Logistic 模型
- 评估 Logistic 模型
- 多类分类
- 统计推断
- 假设检验和置信区间
- 置换检验
- 线性回归的自举(真系数的推断)
- 学生化自举
- P-HACKING
- 向量空间回顾
- 参考表
- Pandas
- Seaborn
- Matplotlib
- Scikit Learn