介绍
在 Web 开发和数据检索的世界里,理解如何在 Python requests 中设置自定义头部(custom headers)是一项至关重要的技能。本教程将指导你如何向你的 Python requests 添加自定义头部,从而开启 Web 抓取、API 交互等更广泛的可能性。
自定义头部允许你控制 Web 服务器和 API 处理你的请求的方式。它们可以帮助你验证请求、指定内容类型、管理缓存,甚至模拟浏览器行为。在本教程结束时,你将掌握实用的知识,能够自定义你的 HTTP 请求以满足特定需求。
理解 HTTP 头部和 Requests 库
在开始编写代码之前,让我们先了解一下 HTTP 头部是什么以及它们为什么重要。
什么是 HTTP 头部?
HTTP 头部是在客户端和服务器之间发送的请求和响应中的键值对。它们提供了关于请求或响应的额外信息,例如内容类型、身份验证凭据或客户端信息。
例如,当你访问一个网站时,你的浏览器会自动包含像 User-Agent(标识你的浏览器)、Accept(指定你可以处理的内容类型)等头部。
安装 Requests 库
Python 的 Requests 库使处理 HTTP 请求变得简单。让我们确保它已安装在我们的环境中:
- 在 WebIDE 中打开一个终端并运行:
pip install requests
你应该看到输出,表明 requests 正在安装或已经安装:
Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (2.28.1)
...
使用 Requests 创建你的第一个 Python 脚本
让我们创建一个简单的 Python 脚本来测试 requests 库:
- 点击 WebIDE 左侧边栏中的 Explorer 图标
- 在文件资源管理器中右键单击并选择“New File”
- 将文件命名为
test_requests.py - 将以下代码添加到文件中:
import requests
## Make a simple GET request to a test website
response = requests.get('https://httpbin.org/get')
## Print the response status code
print(f"Status Code: {response.status_code}")
## Print the response headers (what the server sent back)
print("\nResponse Headers:")
for header, value in response.headers.items():
print(f"{header}: {value}")
## Print the response content
print("\nResponse Content:")
print(response.text[:300] + "...") ## Showing just the first 300 characters
- 通过打开一个终端并执行以下命令来运行脚本:
python test_requests.py
你应该看到类似于以下的输出:
Status Code: 200
Response Headers:
Date: Wed, 12 Apr 2023 10:15:23 GMT
Content-Type: application/json
Content-Length: 267
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Response Content:
{
"args": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.28.1",
"X-Amzn-Trace-Id": "Root=1-643..."
},
"origin": "123.45.67.89",
"url": "https://httpbin.org/get"
}
...
此输出显示:
- 服务器响应的状态码为
200(成功) - 服务器发回的头部
- 响应的实际内容(JSON 格式)
请注意,服务器记录了它从我们这里收到的头部,包括自动生成的 User-Agent 头部,该头部标识我们的请求来自 Python requests 库。
在下一步中,我们将学习如何自定义这些头部,以便更好地控制我们的请求。
在 Python Requests 中设置基本的自定义头部
现在我们已经了解了什么是 HTTP 头部,并且测试了 requests 库,让我们学习如何在我们的请求中设置自定义头部。
为什么设置自定义头部?
设置自定义头部有几个原因:
- 身份验证(Authentication):许多 API 需要在头部发送身份验证令牌
- User-Agent:更改你向网站标识自己的方式
- Content-Type:指定你正在发送的数据的格式
- Accept:指示你可以处理的内容类型
- 自定义头部(Custom Headers):某些 API 需要特定的自定义头部
在 Requests 中设置头部
让我们创建一个新的 Python 脚本来练习设置自定义头部:
- 在 WebIDE 中,创建一个名为
custom_headers.py的新文件 - 添加以下代码:
import requests
## Define the URL we'll make the request to
url = 'https://httpbin.org/headers'
## Define custom headers in a dictionary
custom_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'X-Custom-Header': 'Hello World',
'Accept-Language': 'en-US,en;q=0.9'
}
## Make the request with our custom headers
response = requests.get(url, headers=custom_headers)
## Print the status code
print(f"Status Code: {response.status_code}")
## Print the response content (which shows the headers the server received)
print("\nHeaders received by server:")
print(response.json())
- 运行脚本:
python custom_headers.py
你应该看到类似于以下的输出:
Status Code: 200
Headers received by server:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'httpbin.org', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'X-Custom-Header': 'Hello World', 'X-Amzn-Trace-Id': 'Root=1-6430a123-abc123def456'}}
发生了什么?
在这个脚本中,我们:
创建了一个名为
custom_headers的字典,其中包含三个头部:User-Agent:我们将其从默认的 Python requests 值更改为模拟 Web 浏览器X-Custom-Header:我们发明的完全自定义的头部Accept-Language:指定内容的首选语言
使用
headers参数将我们的头部传递给requests.get()来自 httpbin.org/headers 的响应向我们显示了收到了哪些头部,确认了我们的自定义头部已成功发送
为特定用例修改头部
让我们创建另一个例子,我们假装自己是一个移动设备。这在测试移动端响应式网站时非常有用:
- 创建一个名为
mobile_headers.py的新文件 - 添加以下代码:
import requests
url = 'https://httpbin.org/headers'
## Header to simulate an iPhone
mobile_headers = {
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
}
print("Making request with mobile device headers...")
response = requests.get(url, headers=mobile_headers)
## Print the response content
print(response.json())
- 运行脚本:
python mobile_headers.py
你应该看到类似于以下的输出:
Making request with mobile device headers...
{'headers': {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1', 'X-Amzn-Trace-Id': 'Root=1-6430a456-abc123def456'}}
这表明我们通过设置特定的 User-Agent 头部,成功地告诉服务器我们是一部 iPhone。
使用身份验证头部
自定义头部最常见的用途之一是与 Web 服务和 API 进行身份验证。许多 API 要求你在请求头部中包含身份验证信息。
理解身份验证头部
有几种常见的身份验证方法:
- API 密钥(API Keys):包含在头部或 URL 参数中的简单令牌
- 基本身份验证(Basic Authentication):Base64 编码的用户名和密码
- 持有者令牌(Bearer Tokens):用于 OAuth 和 JWT 身份验证
- 自定义身份验证(Custom Authentication):专有的身份验证方案
让我们探讨如何使用 Python requests 实现这些身份验证方法。
API 密钥身份验证
许多 API 允许使用 API 密钥进行访问。这些通常包含在头部或作为 URL 参数:
- 创建一个名为
api_key_auth.py的新文件 - 添加以下代码:
import requests
url = 'https://httpbin.org/headers'
## Simulating an API key authentication
api_key = 'my_fake_api_key_12345'
## Add the API key to the headers
headers = {
'X-API-Key': api_key,
'User-Agent': 'My API Client/1.0'
}
## Make the request
response = requests.get(url, headers=headers)
## Print results
print(f"Status Code: {response.status_code}")
print("\nHeaders received by server:")
print(response.json())
- 运行脚本:
python api_key_auth.py
你应该看到类似于以下的输出:
Status Code: 200
Headers received by server:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'My API Client/1.0', 'X-API-Key': 'my_fake_api_key_12345', 'X-Amzn-Trace-Id': 'Root=1-6430a789-abc123def456'}}
这确认我们已成功在 X-API-Key 头部中发送了 API 密钥。
基本身份验证
基本身份验证涉及发送以 base64 格式编码的用户名和密码。Requests 库使这变得容易:
- 创建一个名为
basic_auth.py的新文件 - 添加以下代码:
import requests
## URL that requires basic authentication
url = 'https://httpbin.org/basic-auth/user/pass'
## Method 1: Using the auth parameter (recommended)
print("Method 1: Using the auth parameter")
response = requests.get(url, auth=('user', 'pass'))
print(f"Status Code: {response.status_code}")
print(response.json())
## Method 2: Setting the Authorization header manually
print("\nMethod 2: Setting the Authorization header manually")
import base64
## Create the basic auth string: "username:password" encoded in base64
auth_string = base64.b64encode('user:pass'.encode('utf-8')).decode('utf-8')
headers = {
'Authorization': f'Basic {auth_string}'
}
response = requests.get(url, headers=headers)
print(f"Status Code: {response.status_code}")
print(response.json())
- 运行脚本:
python basic_auth.py
你应该看到类似于以下的输出:
Method 1: Using the auth parameter
Status Code: 200
{'authenticated': True, 'user': 'user'}
Method 2: Setting the Authorization header manually
Status Code: 200
{'authenticated': True, 'user': 'user'}
这两种方法都成功地通过了服务的身份验证:
- 方法 1 使用内置的
auth参数,这更方便 - 方法 2 通过手动创建 Authorization 头部,展示了基本身份验证“幕后”的工作方式
持有者令牌身份验证
持有者令牌身份验证通常用于 OAuth 2.0 和基于 JWT 的系统:
- 创建一个名为
bearer_auth.py的新文件 - 添加以下代码:
import requests
url = 'https://httpbin.org/headers'
## Simulate a bearer token (in a real app this would come from an OAuth process)
bearer_token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.Q6CM1qIQkXA_DqyJq9MI0-mnRRCRR3c0SIM-Nul5MZs'
## Add the Authorization header with the Bearer token
headers = {
'Authorization': f'Bearer {bearer_token}'
}
## Make the request
response = requests.get(url, headers=headers)
## Print results
print(f"Status Code: {response.status_code}")
print("\nHeaders received by server:")
print(response.json())
- 运行脚本:
python bearer_auth.py
你应该看到类似于以下的输出:
Status Code: 200
Headers received by server:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Authorization': 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.Q6CM1qIQkXA_DqyJq9MI0-mnRRCRR3c0SIM-Nul5MZs', 'Host': 'httpbin.org', 'X-Amzn-Trace-Id': 'Root=1-6430a901-abc123def456'}}
这显示了在 Authorization 头部中包含持有者令牌的成功请求。
持有者令牌通常在通过 OAuth 2.0 服务器成功完成身份验证过程后获得,但在本例中,我们使用一个示例令牌进行演示。
实际应用和最佳实践
现在你已经学会了如何设置各种类型的自定义头部,让我们探讨一些在实际场景中使用头部的实际应用和最佳实践。
发送和接收 JSON 数据
在使用现代 API 时,JSON 是最常见的数据格式。让我们看看如何为 JSON 请求正确设置头部:
- 创建一个名为
json_requests.py的新文件 - 添加以下代码:
import requests
import json
url = 'https://httpbin.org/post' ## This endpoint accepts POST requests
## Data to send
data = {
'name': 'John Doe',
'email': 'john@example.com',
'message': 'Hello, world!'
}
## Set appropriate headers for JSON
headers = {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
## Method 1: Using the json parameter (recommended)
print("Method 1: Using the json parameter")
response = requests.post(url, json=data, headers=headers)
print(f"Status Code: {response.status_code}")
print(response.json()['headers']) ## Show the headers received
print(f"\nData sent (as received by server): {response.json()['json']}")
## Method 2: Manually converting to JSON
print("\nMethod 2: Manually converting to JSON")
json_data = json.dumps(data)
response = requests.post(url, data=json_data, headers=headers)
print(f"Status Code: {response.status_code}")
print(response.json()['headers']) ## Show the headers received
print(f"\nData sent (as received by server): {response.json()['json']}")
- 运行脚本:
python json_requests.py
你应该看到类似于以下的输出:
Method 1: Using the json parameter
Status Code: 200
{'Accept': 'application/json', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '72', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'X-Amzn-Trace-Id': 'Root=1-6430ab12-abc123def456'}
Data sent (as received by server): {'name': 'John Doe', 'email': 'john@example.com', 'message': 'Hello, world!'}
Method 2: Manually converting to JSON
Status Code: 200
{'Accept': 'application/json', 'Accept-Encoding': 'gzip, deflate', 'Content-Length': '72', 'Content-Type': 'application/json', 'Host': 'httpbin.org', 'X-Amzn-Trace-Id': 'Root=1-6430ab13-abc123def456'}
Data sent (as received by server): {'name': 'John Doe', 'email': 'john@example.com', 'message': 'Hello, world!'}
请注意,这两种方法都有效,但方法 1 更方便,因为 Requests 库为你处理了 JSON 转换。
使用默认头部创建可重用的会话(Session)
如果你需要使用相同的头部进行多个请求,使用 Session 对象可以节省时间并使你的代码更简洁:
- 创建一个名为
session_headers.py的新文件 - 添加以下代码:
import requests
## Create a session object
session = requests.Session()
## Set default headers for all requests made with this session
session.headers.update({
'User-Agent': 'MyCustomApp/1.0',
'Accept-Language': 'en-US,en;q=0.9',
'X-API-Key': 'my_session_api_key'
})
## Make a request using the session - it will include our default headers
print("First request with session:")
response = session.get('https://httpbin.org/headers')
print(response.json())
## Add a custom header just for this request
print("\nSecond request with additional header:")
response = session.get('https://httpbin.org/headers',
headers={'X-Custom-Header': 'Just for this request'})
print(response.json())
## Original headers remain unchanged for future requests
print("\nThird request (original headers only):")
response = session.get('https://httpbin.org/headers')
print(response.json())
- 运行脚本:
python session_headers.py
你应该看到类似于以下的输出:
First request with session:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'httpbin.org', 'User-Agent': 'MyCustomApp/1.0', 'X-API-Key': 'my_session_api_key', 'X-Amzn-Trace-Id': 'Root=1-6430ab45-abc123def456'}}
Second request with additional header:
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'httpbin.org', 'User-Agent': 'MyCustomApp/1.0', 'X-API-Key': 'my_session_api_key', 'X-Custom-Header': 'Just for this request', 'X-Amzn-Trace-Id': 'Root=1-6430ab46-abc123def456'}}
Third request (original headers only):
{'headers': {'Accept': '*/*', 'Accept-Encoding': 'gzip, deflate', 'Accept-Language': 'en-US,en;q=0.9', 'Host': 'httpbin.org', 'User-Agent': 'MyCustomApp/1.0', 'X-API-Key': 'my_session_api_key', 'X-Amzn-Trace-Id': 'Root=1-6430ab47-abc123def456'}}
使用会话是最佳实践,原因如下:
- 提高性能(连接池)
- 跨请求的头部一致性
- 自动处理 Cookie
- 根据需要添加每个请求的自定义
使用头部的最佳实践
总而言之,以下是在使用 HTTP 头部时要遵循的一些最佳实践:
- 对于对同一域名的多个请求,使用 Session 对象
- 为你要发送的数据正确设置 Content-Type 头部
- 正确处理身份验证 - 尽可能使用内置的身份验证
- 保护敏感信息 - 不要对 API 密钥或令牌进行硬编码
- 仔细遵循 API 文档,了解所需的头部
这是一个演示这些最佳实践的最终示例:
- 创建一个名为
best_practices.py的新文件 - 添加以下代码:
import requests
import os
## In a real application, get these from environment variables or a secure configuration
## For this example, we're keeping it simple
API_KEY = os.environ.get('API_KEY', 'default_api_key')
BASE_URL = 'https://httpbin.org'
def create_api_client():
"""Create a reusable session with default headers."""
session = requests.Session()
## Set common headers
session.headers.update({
'User-Agent': 'MyApp/1.0',
'X-API-Key': API_KEY,
'Accept': 'application/json'
})
return session
def get_data(client, endpoint):
"""Make a GET request to the specified endpoint."""
url = f"{BASE_URL}/{endpoint}"
response = client.get(url)
return response.json()
def post_data(client, endpoint, data):
"""Make a POST request with JSON data."""
url = f"{BASE_URL}/{endpoint}"
response = client.post(url, json=data)
return response.json()
## Usage example
def main():
## Create the API client
client = create_api_client()
## GET request example
print("Making GET request...")
get_response = get_data(client, 'headers')
print(f"Headers sent: {get_response['headers']}")
## POST request example
print("\nMaking POST request...")
data = {'name': 'John', 'age': 30}
post_response = post_data(client, 'post', data)
print(f"Data received by server: {post_response['json']}")
if __name__ == '__main__':
main()
- 运行脚本:
python best_practices.py
你应该看到类似于以下的输出:
Making GET request...
Headers sent: {'Accept': 'application/json', 'Accept-Encoding': 'gzip, deflate', 'Host': 'httpbin.org', 'User-Agent': 'MyApp/1.0', 'X-API-Key': 'default_api_key', 'X-Amzn-Trace-Id': 'Root=1-6430ab78-abc123def456'}
Making POST request...
Data received by server: {'name': 'John', 'age': 30}
此示例演示了一种使用自定义头部进行 HTTP 请求的结构化方法,遵循最佳实践,例如创建可重用的会话,将代码组织成函数,以及避免对敏感信息进行硬编码。
总结
在本教程中,你学习了如何在 Python requests 中使用自定义头部,这是进行有效 Web 通信和 API 集成的必备技能。
你现在了解:
- 什么是 HTTP 头部以及它们为什么对 Web 请求很重要
- 如何为单个请求设置自定义头部
- 使用头部的各种身份验证方法(API 密钥、基本身份验证、持有者令牌)
- 如何正确处理 JSON 数据和内容类型头部
- 使用会话对象管理头部的最佳实践
这些技能将使你能够更有效地与任何 Web API 交互,访问受保护的资源,控制你的请求的处理方式,并构建更复杂的 Web 应用程序。
在你继续发展你的 Python 技能时,请记住,理解 HTTP 基础知识,如头部、状态码和内容类型,将帮助你解决问题并在你的 Web 应用程序中实现更高级的功能。



