在日常的 Web 开发和数据抓取工作中,你是否曾经遇到过需要与各种 API 进行交互的场景?或者你是否需要模拟浏览器行为来获取网页数据?这时,掌握 HTTP 请求方法就显得至关重要。作为 Python 开发者,我们非常幸运地拥有 requests 这个优雅且强大的库。它不仅简化了 HTTP 通信的复杂度,还让我们能够以一种非常人性化的方式发送网络请求。
在这篇文章中,我们将深入探讨 Python 的 requests 模块,特别是它如何处理各种 HTTP 请求方法(如 GET、POST、PUT、DELETE 等)。我们将从基础概念出发,通过实际代码示例,一步步演示如何构建健壮的网络应用,并分享一些在实际开发中积累的实战经验和避坑指南。
为什么 HTTP 请求方法如此重要?
HTTP(超文本传输协议)是互联网上客户端与服务器之间通信的基石。我们可以把 Web 浏览器(如 Chrome 或 Firefox)看作是一个客户端,而托管网站的应用程序则是服务器。当我们要获取数据时,我们会发送请求;服务器处理并返回响应。
requests 库内置了多种方法,让我们可以轻松地使用 GET、POST、PUT、PATCH 或 HEAD 请求向指定的 URI(统一资源标识符)发起调用。理解这些方法的区别,是设计符合 RESTful 架构风格 API 的第一步,也是编写高效网络爬虫的关键。
HTTP 请求方法概览
在开始写代码之前,让我们先通过下表快速了解这些核心方法及其主要用途。
Description
—
用于从指定的 URI 检索信息。这是最常见的请求类型,用于获取数据。
用于向服务器发送数据以创建/更新资源。通常用于提交表单或上传文件。
用于将数据上传到服务器。如果 URI 指向已有资源,则更新它;否则创建新资源。
用于删除指定的资源。
与 GET 类似,但服务器只返回响应头,不包含响应体。常用于检查资源是否存在。
用于对资源进行部分修改。与 PUT 不同,PATCH 不需要发送完整的资源实体。### 1. GET 请求:获取数据的利器
GET 方法是我们最熟悉的伙伴。它的主要目的是通过给定的 URI 从指定服务器检索信息。当你使用 GET 方法时,参数通常会附加在 URL 后面进行发送。页面和编码后的信息由 INLINECODEe4e84ed1 字符分隔,参数之间用 INLINECODE1e84f020 连接。
一个典型的 URL 示例:
https://www.google.com/search?q=hello+world
在这里,q=hello+world 就是通过 GET 方法传递给服务器的参数。
#### 如何通过 Python Requests 发起 GET 请求
Python 的 INLINECODEbb332797 模块提供了一个非常直观的 INLINECODE3220484d 方法。
基础语法:
requests.get(url, params={key: value}, args)
实战示例:访问 GitHub API
让我们尝试向 GitHub 的 API 发起一个请求,获取用户信息。这是我们与外部世界交互的第一步。
import requests
# 定义目标 API 端点
# 注意:为了防止 URL 拼写错误,建议直接复制有效的 API 地址
api_url = ‘https://api.github.com/users/naveenkrnl‘
try:
# 发起 GET 请求
response = requests.get(api_url)
# 检查状态码
# 200 表示请求成功,4xx 表示客户端错误,5xx 表示服务器错误
if response.status_code == 200:
print(f"请求成功!状态码:{response.status_code}")
# 打印响应内容的 JSON 格式(如果 API 返回的是 JSON)
user_data = response.json()
print(f"用户 ID: {user_data.get(‘id‘)}")
print(f"用户名: {user_data.get(‘name‘)}")
else:
print(f"请求失败,状态码:{response.status_code}")
except requests.exceptions.RequestException as e:
# 捕获网络相关的异常,如连接超时或 DNS 解析失败
print(f"发生网络错误: {e}")
#### GET 请求的最佳实践
在使用 GET 请求时,我们不仅要会发送请求,还要学会处理响应。response 对象包含了非常有用的信息:
-
response.text:以字符串形式返回响应内容。Requests 会自动根据响应头推测内容编码。 -
response.content:以字节形式返回响应内容。这在下载二进制文件(如图片、PDF)时非常有用。 -
response.json():如果响应内容是 JSON 格式,我们可以直接将其解析为 Python 字典,方便后续数据处理。
优化技巧:添加超时和 Headers
在真实的生产环境中,我们绝不能让程序无限期等待。我们应当始终设置 INLINECODE554a2b91 参数。此外,有些网站会检查 INLINECODEdbf9b1cc 来阻止爬虫,我们可以自定义 Headers 来伪装成浏览器。
import requests
headers = {
‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36‘
}
# 设置超时时间为 5 秒,连接 2 秒,读取 5 秒
try:
response = requests.get(‘https://httpbin.org/get‘, headers=headers, timeout=5)
print(response.text)
except requests.Timeout:
print("请求超时,请检查网络或稍后重试。")
2. POST 请求:向服务器发送数据
当我们需要向服务器提交数据时,GET 请求就不够用了(GET 参数拼接在 URL 上,既不安全也有长度限制)。这时,POST 请求就派上用场了。POST 方法请求 Web 服务器接受请求消息体中包含的数据,最常见的是为了存储这些数据。它广泛用于上传文件或提交已填写的 Web 表单。
#### 如何通过 Python Requests 发起 POST 请求
Python 的 INLINECODE4a20b24d 模块提供了 INLINECODE6295a9e7 方法。它的强大之处在于,我们可以非常轻松地传递各种格式的数据。
基础语法:
requests.post(url, data={key: value}, json={key: value}, args)
#### 实战场景:提交表单数据与 JSON 数据
让我们通过 httpbin.org 这个强大的测试网站来演示 POST 请求的两种常见用法。
示例 1:发送表单编码数据
这是模拟浏览器提交传统 HTML 表单的方式。requests 会自动将字典编码为表单格式。
import requests
# 目标 URL
url = ‘https://httpbin.org/post‘
# 准备要发送的数据
form_data = {
‘username‘: ‘test_user‘,
‘password‘: ‘secret_password‘,
‘submit‘: ‘Login‘
}
try:
# 发起 POST 请求
# data 参数默认使用 application/x-www-form-urlencoded 类型
response = requests.post(url, data=form_data)
if response.status_code == 200:
# 打印服务器返回的 JSON 数据
# httpbin.org 会把我们发送的数据反射回来,方便我们调试
result = response.json()
print("发送成功!服务器返回的数据:")
print(result[‘form‘])
except requests.exceptions.RequestException as e:
print(f"请求出错: {e}")
示例 2:发送 JSON 数据(现代 API 开发标准)
在现代 Web 开发中,前后端交互通常使用 JSON 格式。Requests 库非常贴心地提供了 INLINECODE9ed3b04e 参数,它会自动帮我们将 Python 字典序列化为 JSON 字符串,并设置正确的 INLINECODEdae3a29f 头部为 application/json。
import requests
import json
url = ‘https://httpbin.org/post‘
# 这是一个复杂的嵌套字典,非常适合转换为 JSON
payload = {
‘event_id‘: 12345,
‘participant‘: {
‘name‘: ‘Alice‘,
‘skills‘: [‘Python‘, ‘Data Analysis‘]
},
‘timestamp‘: ‘2023-10-27T10:00:00‘
}
try:
# 使用 json 参数发送请求
response = requests.post(url, json=payload)
if response.status_code == 200:
# 验证发送的数据格式是否正确
result = response.json()
# 检查 ‘json‘ 字段,看服务器是否正确解析了我们发送的 JSON
print("JSON 数据发送成功:")
print(json.dumps(result[‘json‘], indent=4))
except requests.exceptions.RequestException as e:
print(f"请求出错: {e}")
3. PUT 请求:更新资源的完整方案
PUT 方法通常用于更新资源。根据 HTTP 规范,PUT 请求会将包含的实体存储在提供的 URI 下。如果 URI 指向的是已有的资源,则修改该资源(通常是全量更新);如果 URI 没有指向现有资源,则服务器可以使用该 URI 创建该资源。
#### 如何通过 Python Requests 发起 PUT 请求
import requests
url = ‘https://httpbin.org/put‘
# 假设我们要更新用户资料的所有字段
updated_data = {
‘id‘: 1,
‘name‘: ‘John Doe‘,
‘email‘: ‘[email protected]‘,
‘role‘: ‘Administrator‘
}
try:
# 发起 PUT 请求
response = requests.put(url, data=updated_data)
if response.status_code == 200:
print("资源更新成功!")
print(response.json())
except requests.exceptions.RequestException as e:
print(f"更新资源时出错: {e}")
4. PATCH 请求:部分更新更高效
在实际开发中,我们经常只需要修改资源的某一个字段,而不是整个资源。如果我们使用 PUT,就需要把所有字段(包括未修改的)都重新发送一遍,这既浪费带宽也容易出错。这时,PATCH 方法就是更好的选择。
#### PATCH 实战示例
让我们看一个只更新用户邮箱的例子。
import requests
url = ‘https://httpbin.org/patch‘
# 只包含需要修改的字段
partial_update = {
‘email‘: ‘[email protected]‘
}
try:
# 发起 PATCH 请求
response = requests.patch(url, data=partial_update)
if response.status_code == 200:
print("部分更新成功!")
except requests.exceptions.RequestException as e:
print(f"更新失败: {e}")
PUT vs PATCH 的关键区别:
你可以这样理解:PUT 是“替换整个文件”,而 PATCH 是“在文件里修改几行”。
5. DELETE 请求:清理无用资源
DELETE 方法非常直观,用于删除指定的资源。在编写 CMS(内容管理系统)或清理脚本时,这个方法非常有用。
import requests
url = ‘https://httpbin.org/delete‘
try:
response = requests.delete(url)
if response.status_code == 200:
print("资源已成功删除。")
except requests.exceptions.RequestException as e:
print(f"删除资源失败: {e}")
6. HEAD 请求:高效检查资源状态
HEAD 方法请求的响应与 GET 请求相同,但不包含响应体。这意味着我们只获取 HTTP 头部信息(如内容类型、内容长度、最后修改时间),而不下载实际内容。
应用场景: 在下载大文件之前,我们可以先用 HEAD 请求检查文件大小或是否存在,从而节省带宽和时间。
import requests
url = ‘https://www.python.org/static/img/python-logo.png‘
try:
response = requests.head(url)
# 检查资源是否存在
if response.status_code == 200:
# 获取文件大小
file_size = response.headers.get(‘Content-Length‘)
print(f"资源可用!文件大小为: {file_size} 字节")
else:
print("资源不存在。")
except requests.exceptions.RequestException as e:
print(f"检查资源时出错: {e}")
进阶话题:处理会话与异常
#### 使用 Session 保持持久连接
如果你需要向同一主机发送多个请求(比如爬取一个网站的多个页面),使用 requests.Session() 是最佳实践。Session 对象会跨请求保持参数(如 cookies),并且利用 TCP 连接复用(Keep-Alive),从而显著提高性能。
import requests
# 创建一个 session 对象
with requests.Session() as session:
# 登录请求(这会在 session 中保存 cookie)
session.post(‘https://httpbin.org/post‘, data={‘user‘: ‘admin‘})
# 后续请求会自动带上之前的 cookie
response = session.get(‘https://httpbin.org/cookies‘)
print(response.text)
#### 常见异常处理策略
网络是不可靠的。专业的开发者必须处理各种异常情况。Requests 库定义了多种异常,如 INLINECODE84a7b30d(网络连接问题)、INLINECODE36ccf423(无效的 HTTP 响应)、INLINECODEfffc7430(请求超时)等。我们建议始终使用 INLINECODE05f3508f 块包裹网络请求代码,确保程序在遇到错误时不会崩溃,而是能够优雅地降级或重试。
总结与下一步
通过这篇文章,我们深入了解了 Python requests 库的核心功能。从简单的 GET 数据获取,到复杂的 POST JSON 数据提交,再到 PUT、PATCH、DELETE 等资源操作,这些方法构成了现代 Web 交互的基础。
关键要点回顾:
- GET 用于安全获取数据,POST 用于创建数据,PUT 用于全量更新,PATCH 用于部分更新,DELETE 用于删除。
- 始终使用
response.status_code来检查请求是否成功,而不要假设请求永远会成功。 - 利用 INLINECODE7affa0e1 参数防止程序卡死,使用 INLINECODE9d9c7f14 提高多请求场景的性能。
- 在生产环境中,完善的异常处理机制是不可或缺的。
现在,你已经具备了与几乎任何 Web API 进行交互的能力。下一步,你可以尝试结合这些知识,编写一个实际的 API 客户端,或者构建一个简单的网络爬虫来收集你感兴趣的数据。祝你编码愉快!