1. 初识Requests库中的GET方法
作为一名Python开发者,我经常需要与各种Web API打交道。在这个过程中,Requests库成为了我最得力的助手。今天我想重点聊聊其中最基础但使用频率最高的GET方法。
Requests库的GET方法远不止是简单的数据获取工具。在实际项目中,我发现它能处理各种复杂的场景:
- 从RESTful API获取JSON数据
- 爬取网页内容进行分析
- 检查网站可用性
- 获取远程文件
- 与各种云服务API交互
import requests
# 最基本的GET请求示例
response = requests.get('https://api.github.com/events')
print(response.status_code) # 输出状态码
print(response.json()) # 解析JSON响应
注意:虽然GET方法看起来简单,但在生产环境中使用时需要考虑超时设置、重试机制、异常处理等细节,否则很容易出现不可预知的问题。
2. GET方法的参数详解
2.1 URL参数处理
GET请求最常用的功能就是通过URL传递参数。Requests库让这个过程变得异常简单:
params = {
'key1': 'value1',
'key2': ['value2', 'value3'],
'key3': None # 这个参数会被自动忽略
}
response = requests.get('https://httpbin.org/get', params=params)
print(response.url) # 查看最终构造的URL
Requests会自动处理参数编码和特殊字符,甚至能正确处理列表类型的参数值。我在实际项目中发现,这个特性在处理复杂查询条件时特别有用。
2.2 请求头定制
很多API需要特定的请求头才能正常工作。Requests允许我们轻松定制请求头:
headers = {
'User-Agent': 'MyApp/1.0',
'Accept': 'application/json',
'Authorization': 'Bearer your_token_here'
}
response = requests.get('https://api.example.com/data', headers=headers)
我经常遇到的一个坑是忘记设置User-Agent,导致某些网站返回403错误。建议总是设置一个有意义的User-Agent。
2.3 超时控制
没有设置超时的网络请求是非常危险的。我曾经因为忘记设置超时,导致整个应用被卡死:
try:
# 设置连接超时3秒,读取超时5秒
response = requests.get('https://example.com', timeout=(3, 5))
except requests.exceptions.Timeout:
print("请求超时,请检查网络或稍后重试")
3. 响应处理技巧
3.1 状态码检查
虽然Requests不会自动检查状态码,但我们可以使用raise_for_status()方法:
response = requests.get('https://example.com/api')
try:
response.raise_for_status()
except requests.exceptions.HTTPError as err:
print(f"HTTP错误发生: {err}")
3.2 内容解析
根据响应内容的不同,Requests提供了多种解析方式:
# 文本内容
text_content = response.text
# 二进制内容(如图片)
binary_content = response.content
# JSON内容(自动解析)
json_data = response.json()
# 流式处理大文件
with requests.get('https://example.com/large_file', stream=True) as r:
for chunk in r.iter_content(chunk_size=8192):
process_chunk(chunk)
3.3 编码处理
编码问题经常让人头疼。我发现设置正确的响应编码可以避免很多问题:
response.encoding = 'utf-8' # 显式设置编码
print(response.text)
如果不知道编码是什么,可以使用apparent_encoding属性,它会根据内容猜测可能的编码:
response.encoding = response.apparent_encoding
4. 高级应用场景
4.1 会话保持
对于需要登录的网站,使用Session对象可以保持cookies:
with requests.Session() as session:
# 先登录
session.post('https://example.com/login', data={'user': 'me', 'pass': 'secret'})
# 后续请求会自动携带cookies
response = session.get('https://example.com/protected')
4.2 重试机制
网络不稳定时,自动重试很有必要。我通常使用urllib3的Retry:
from urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
retry_strategy = Retry(
total=3,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504]
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session = requests.Session()
session.mount("https://", adapter)
session.mount("http://", adapter)
response = session.get("https://example.com")
4.3 代理设置
在某些环境下,需要通过代理访问外部资源:
proxies = {
'http': 'http://10.10.1.10:3128',
'https': 'http://10.10.1.10:1080',
}
response = requests.get('https://example.com', proxies=proxies)
5. 常见问题与解决方案
5.1 429 Too Many Requests错误
当遇到429错误时,说明请求过于频繁。我的处理方法是:
- 检查API的速率限制
- 添加适当的延迟
- 实现指数退避算法
import time
from requests.exceptions import HTTPError
def make_request_with_retry(url):
retry_count = 0
max_retries = 3
base_delay = 1 # 初始延迟1秒
while retry_count < max_retries:
try:
response = requests.get(url)
response.raise_for_status()
return response
except HTTPError as err:
if err.response.status_code == 429:
retry_count += 1
delay = base_delay * (2 ** retry_count) # 指数退避
print(f"遇到429错误,等待{delay}秒后重试...")
time.sleep(delay)
else:
raise
raise Exception("达到最大重试次数")
5.2 SSL证书验证问题
在某些测试环境中,可能需要禁用SSL验证(生产环境不推荐):
response = requests.get('https://example.com', verify=False)
更好的做法是指定自定义CA证书:
response = requests.get('https://example.com', verify='/path/to/cert.pem')
5.3 性能优化
对于高频请求,我总结了一些优化技巧:
- 使用连接池
- 启用keep-alive
- 合理设置超时
- 批量处理请求
# 启用连接池
session = requests.Session()
adapter = requests.adapters.HTTPAdapter(pool_connections=10, pool_maxsize=10)
session.mount('https://', adapter)
# 批量请求
urls = ['https://example.com/1', 'https://example.com/2']
responses = [session.get(url) for url in urls]
6. 实际项目中的最佳实践
经过多个项目的实践,我总结出以下经验:
- 总是封装请求逻辑,而不是直接使用requests.get
- 记录详细的请求日志,包括URL、参数、耗时等
- 实现统一的错误处理机制
- 考虑添加请求限流功能
- 监控API的响应时间和成功率
import logging
from datetime import datetime
logger = logging.getLogger(__name__)
def safe_get(url, params=None, headers=None, timeout=5):
start_time = datetime.now()
try:
response = requests.get(
url,
params=params,
headers=headers,
timeout=timeout
)
response.raise_for_status()
return response
except Exception as e:
logger.error(
f"请求失败: {url}, 参数: {params}, 错误: {str(e)}",
exc_info=True
)
raise
finally:
duration = (datetime.now() - start_time).total_seconds()
logger.info(f"请求完成: {url}, 耗时: {duration:.2f}s")
7. 测试与调试技巧
7.1 使用httpbin测试
httpbin.org是一个非常好的测试API:
# 测试GET参数
response = requests.get('https://httpbin.org/get', params={'test': 'value'})
print(response.json())
# 测试请求头
response = requests.get('https://httpbin.org/headers', headers={'X-Test': 'true'})
print(response.json())
7.2 调试请求
有时候需要查看实际发送的请求信息:
# 启用详细日志
import http.client
http.client.HTTPConnection.debuglevel = 1
# 发送请求
requests.get('https://example.com')
7.3 使用Postman对比
当请求结果不符合预期时,我通常会:
- 先用Postman测试确保API正常工作
- 对比Postman和代码中的参数、头信息
- 逐步排查差异
8. 与其他工具集成
8.1 结合pytest测试
编写API测试用例:
import pytest
def test_get_request():
response = requests.get('https://api.example.com/items')
assert response.status_code == 200
assert 'items' in response.json()
8.2 与aiohttp配合
对于需要高性能的场景,可以考虑异步请求:
import aiohttp
import asyncio
async def fetch(session, url):
async with session.get(url) as response:
return await response.text()
async def main():
async with aiohttp.ClientSession() as session:
html = await fetch(session, 'http://example.com')
print(html)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
8.3 在Django/Flask中使用
在Web应用中封装请求逻辑:
# Django示例
from django.core.cache import cache
def get_cached_data(url):
data = cache.get(url)
if data is None:
response = requests.get(url)
data = response.json()
cache.set(url, data, timeout=60*5) # 缓存5分钟
return data
9. 安全注意事项
- 不要在代码中硬编码敏感信息
- 使用环境变量管理API密钥
- 验证所有输入数据
- 处理敏感数据时要小心
import os
# 从环境变量获取API密钥
api_key = os.getenv('API_KEY')
headers = {'Authorization': f'Bearer {api_key}'}
response = requests.get('https://api.example.com/data', headers=headers)
10. 性能监控与优化
10.1 请求计时
了解请求耗时有助于发现性能瓶颈:
import time
start = time.time()
response = requests.get('https://example.com')
elapsed = time.time() - start
print(f"请求耗时: {elapsed:.2f}秒")
10.2 使用CDN加速
对于静态资源,考虑使用CDN:
# 通过CDN获取jQuery
response = requests.get('https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js')
10.3 压缩传输
启用gzip压缩可以显著减少传输数据量:
headers = {'Accept-Encoding': 'gzip'}
response = requests.get('https://example.com', headers=headers)
print(f"压缩后大小: {len(response.content)} bytes")
在实际项目中,我发现合理使用Requests库的GET方法可以解决90%的数据获取需求。关键在于理解其工作原理,并针对特定场景做适当的调整和优化。



5万+

被折叠的 条评论
为什么被折叠?



