grequests:异步 HTTP 请求的利器
grequests 是一个基于 gevent 和 requests 的 Python 库,专为处理并发 HTTP 请求而设计。它不仅保留了 requests 库的易用性,还通过 gevent 的异步能力显著提高了并发请求的处理效率。以下是 grequests 的一些核心功能和使用方法。
安装 grequests
安装 grequests 非常简单,只需运行以下命令:
pip install grequests基础功能
发送并发请求
grequests 的核心功能是能够异步发送多个 HTTP 请求。以下示例展示了如何同时发送多个 GET 请求:
import grequests
# 准备要请求的 URL 列表
urls = [
'http://api1.example.com',
'http://api2.example.com',
'http://api3.example.com'
]
# 创建异步请求对象
requests = (grequests.get(u) for u in urls)
# 发送请求并获取响应
responses = grequests.map(requests)
# 处理响应
for response in responses:
if response is not None:
print(response.status_code)异常处理
在处理多个请求时,合理的异常处理非常重要。以下代码展示了如何处理请求过程中的异常:
import grequests
def exception_handler(request, exception):
print(f"请求失败: {request.url}")
print(f"异常信息: {exception}")
urls = [
'http://api.example.com',
'http://invalid-url.com'
]
requests = (grequests.get(u) for u in urls)
responses = grequests.map(requests, exception_handler=exception_handler)设置请求参数
grequests 支持设置各种请求参数,包括 headers、超时时间等:
import grequests
# 准备请求配置
headers = {'User-Agent': 'Custom User Agent'}
timeout = 5
# 创建带参数的请求
requests = [
grequests.get('http://api.example.com', headers=headers, timeout=timeout),
grequests.post('http://api.example.com/data', json={'key': 'value'}, headers=headers)
]
# 发送请求
responses = grequests.map(requests)高级功能
请求池管理
对于大量请求,可以通过设置并发数来控制请求池的大小:
import grequests
def send_requests_in_pool(urls, pool_size=5):
# 创建请求对象
reqs = (grequests.get(url) for url in urls)
# 使用 imap 限制并发数
responses = grequests.imap(reqs, size=pool_size)
# 处理响应
for response in responses:
if response and response.status_code == 200:
print(f"Success: {response.url}")
# 使用示例
urls = [f'http://api.example.com/item/{i}' for i in range(100)]
send_requests_in_pool(urls, pool_size=10)自定义会话
使用自定义会话可以在多个请求之间共享配置:
import grequests
from requests.sessions import Session
def create_custom_session():
session = Session()
session.headers.update({
'User-Agent': 'Custom User Agent',
'Authorization': 'Bearer token'
})
return session
# 使用自定义会话发送请求
urls = ['http://api.example.com/resource1', 'http://api.example.com/resource2']
requests = [grequests.get(url, session=create_custom_session()) for url in urls]
responses = grequests.map(requests)实际应用场景
批量数据抓取
在需要从多个页面抓取数据时,grequests 可以显著提高效率:
import grequests
from bs4 import BeautifulSoup
class WebScraper:
def __init__(self, base_url):
self.base_url = base_url
def scrape_pages(self, page_nums):
# 生成 URL 列表
urls = [f"{self.base_url}/page/{num}" for num in page_nums]
# 创建请求
requests = (grequests.get(url) for url in urls)
# 发送请求并获取响应
responses = grequests.map(requests)
# 解析响应
results = []
for response in responses:
if response and response.status_code == 200:
soup = BeautifulSoup(response.text, 'html.parser')
# 提取数据
data = soup.find_all('div', class_='content')
results.extend(data)
return results
# 使用示例
scraper = WebScraper('http://example.com')
data = scraper.scrape_pages(range(1, 10))API 并发请求
在需要同时调用多个 API 端点时,可以使用 grequests 提高性能:
import grequests
import json
class APIClient:
def __init__(self, base_url, api_key):
self.base_url = base_url
self.headers = {
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
}
def batch_request(self, endpoints):
# 准备请求
requests = [
grequests.get(f"{self.base_url}{endpoint}", headers=self.headers)
for endpoint in endpoints
]
# 发送请求
responses = grequests.map(requests)
# 处理响应
results = []
for response in responses:
if response and response.status_code == 200:
results.append(response.json())
return results
# 使用示例
client = APIClient('http://api.example.com', 'your-api-key')
endpoints = ['/users', '/products', '/orders']
data = client.batch_request(endpoints)grequests 是一个强大而简洁的异步 HTTP 请求解决方案。通过结合 gevent 的异步能力和 requests 库的友好接口,它使得处理并发 HTTP 请求变得既简单又高效。在实际应用中,无论是进行大规模数据抓取还是调用多个 API 接口,grequests 都能显著提升应用程序的性能。通过合理使用请求池管理和异常处理机制,开发者可以构建出稳定可靠的并发请求系统。