Skip to content

Requests - HTTP 请求工作原理?

Python requests 库如何进行 HTTP 请求

Section titled “Python requests 库如何进行 HTTP 请求”

超文本传输协议(Hypertext Transfer Protocol,简称 HTTP)是万维网数据通信的基础。当你浏览网站时,你的浏览器会向服务器发送 HTTP 请求,服务器则回复 HTTP 响应。Python 的 requests 库是一个功能强大而又简单易用的工具,它允许你通过编程方式发送这些 HTTP 请求,从而轻松地与 Web 服务和 API 进行交互。

这种交互遵循客户端-服务器模型。你的 Python 脚本使用 requests 库作为客户端。它构建一个 HTTP 请求并将其发送到 Web 服务器。服务器处理此请求并发送回一个 HTTP 响应,该响应可能包含你请求的数据(如网页或 JSON 数据),或关于你的请求是否成功的信息。

一个 HTTP 请求包含几个关键组成部分:

这是你想在 Web 上与之交互的资源的地址。例如:https://api.example.com/data。它指定了协议(例如 https 或 http)、主机名(例如 api.example.com)以及资源的路径(例如 /data)。

这定义了要对资源执行的操作。常用方法包括:

GET:从服务器检索数据。例如,获取网页或用户信息。

POST:向服务器发送数据以创建新资源。例如,提交表单或创建新用户。

PUT:向服务器发送数据以更新现有资源,如果资源不存在则创建它。例如,更新用户资料。

DELETE:从服务器删除资源。例如,删除用户账户。

Headers 提供了关于请求的元数据(metadata),例如发送内容的类型(Content-Type)或认证令牌(Authorization)。requests 库通常会自动处理常用的 Headers,但你也可以根据需要进行自定义。

4. Body(主体)或 Payload(负载)

Section titled “4. Body(主体)或 Payload(负载)”

Body 包含发送到服务器的实际数据,通常用于 POST 或 PUT 请求。这可以是表单数据、JSON、XML 或其他格式。

使用 Python 的 requests 库发送请求

Section titled “使用 Python 的 requests 库发送请求”

首先,请确保已安装 requests 库(pip install requests),然后将其导入到你的 Python 脚本中:

import requests

GET 请求用于检索信息。这是一个基本示例:

response = requests.get('https://jsonplaceholder.typicode.com/todos/1')
print(response.text) # Print the response content as text

要将数据作为查询参数发送到 URL 中(例如,https://api.example.com/users?id=9&username=Delphine),请使用带有字典的 params 参数:

payload = {'id': '9', 'username': 'Delphine'}
response = requests.get('https://jsonplaceholder.typicode.com/users', params=payload)
# The actual URL requested will be: https://jsonplaceholder.typicode.com/users?id=9&username=Delphine
print(response.url) # You can inspect the URL that was actually requested

requests 库会自动对 params 字典进行 URL 编码,并将其附加到 URL 中。

POST 请求用于向服务器发送数据,通常用于创建新资源。

要以 HTML 表单的形式发送数据(form-encoded,application/x-www-form-urlencoded),请使用 data 参数:

form_payload = {'title': 'My New Post', 'body': 'This is the content.', 'userId': 1}
response = requests.post('https://jsonplaceholder.typicode.com/posts', data=form_payload)
print(response.status_code) # Check the status code (e.g., 201 for created)
print(response.json()) # See the server's response (often the created object)

对于发送 JSON 数据(在现代 API 中很常见),请使用 json 参数。requests 会自动将你的 Python 字典序列化(serialize)为 JSON 字符串,并设置 Content-Type 头为 application/json:

json_payload = {'title': 'Another Post', 'body': 'JSON content here.', 'userId': 5}
response = requests.post('https://jsonplaceholder.typicode.com/posts', json=json_payload)
print(response.status_code)
print(response.json())

PUT 请求通常用于更新特定 URL 上的现有资源。如果资源不存在,根据服务器的实现,PUT 可能会创建它。

update_payload = {'id': 1, 'title': 'Updated Title', 'body': 'Updated body content.', 'userId': 1}
# The resource ID (e.g., 1) is often part of the URL for PUT requests.
response = requests.put('https://jsonplaceholder.typicode.com/posts/1', json=update_payload)
print(response.status_code)
print(response.json())

DELETE 请求用于删除由 URL 标识的资源。

# The resource ID (e.g., 1) is part of the URL.
response = requests.delete('https://jsonplaceholder.typicode.com/posts/1')
print(response.status_code) # Should be 200 or 204 if successful (server dependent)
# DELETE requests often return an empty body or a success message.

发出请求后,requests 返回的 response 对象包含服务器的响应。以下是一些重要属性:

response.status_code 属性提供 HTTP 状态码,表示请求的结果。常用代码包括:

200 OK:请求成功。

201 Created:请求成功,并创建了新资源(POST/PUT 常见)。

204 No Content:请求成功,但没有内容返回(DELETE 常见)。

400 Bad Request:由于语法无效,服务器无法理解请求。

401 Unauthorized:需要认证,认证失败或尚未提供。

403 Forbidden:服务器理解请求,但拒绝授权。

404 Not Found:在服务器上找不到请求的资源。

500 Internal Server Error:服务器遇到意外情况,阻止了请求的完成。

检查状态码是一个好习惯。你可以使用 response.raise_for_status(),如果请求返回了非成功状态码(4xx 或 5xx),它将引发 HTTPError 异常。

有关完整列表,请参阅 MDN Web Docs 关于 HTTP 状态码的文档。

你可以通过多种方式访问响应的 body:

response.text:响应的内容,以 Unicode 形式表示。requests 会尝试从服务器指定的编码进行解码。

response.content:响应的内容,以字节(bytes)形式表示。对于图像或文件等非文本响应非常有用。

response.json():如果响应内容是 JSON,此方法会将其解析为 Python 字典或列表。如果内容不是有效的 JSON,它将引发 JSONDecodeError 异常。

import requests
response = requests.get('https://jsonplaceholder.typicode.com/todos/1')
if response.status_code == 200:
try:
data = response.json()
print(f"Title: {data['title']}")
except requests.exceptions.JSONDecodeError:
print("Response was not in JSON format")
else:
print(f"Request failed with status code: {response.status_code}")

response.headers 是一个类似字典的对象,包含服务器返回的响应 Headers(例如 Content-Type、Date、Server)。Headers 是不区分大小写的。

requests 无缝处理 HTTPS (HTTP Secure) 连接。当你向 https:// URL 发送请求时,requests 会自动验证服务器的 SSL 证书,确保你的通信是加密和安全的。这是保护敏感数据的关键特性。

HTTP 是 Web 上客户端-服务器通信的协议,定义了诸如 GET、POST、PUT 和 DELETE 等方法。

Python 的 requests 库简化了发送这些 HTTP 请求的过程。

对于 GET 请求的查询字符串(query strings),使用 params;对于 form-encoded 的 POST/PUT body,使用 data;对于 JSON-encoded 的 POST/PUT body,使用 json。

始终检查 response.status_code(或使用 response.raise_for_status()),并根据需要使用 .text、.content 或 .json() 处理响应内容。

对 HTTP 请求和 requests 库的这种基础理解将使你能够与各种 Web 服务、API 交互,并从互联网检索各种数据。