Python发送HTTP请求及超时重试技巧
时间:2025-06-24 10:38:19 182浏览 收藏
积累知识,胜过积蓄金银!毕竟在文章开发的过程中,会遇到各种各样的问题,往往都是一些细节知识点还没有掌握好而导致的,因此基础知识点的积累是很重要的。下面本文《Python发送HTTP请求及超时重试方法》,就带大家讲解一下知识点,若是你对本文感兴趣,或者是想搞懂其中某个知识点,就请你继续往下看吧~
要自定义重试策略,可使用urllib3.util.retry.Retry或自定义HTTPAdapter。1. 使用Retry设置总重试次数、退避因子、需重试的状态码及允许重试的请求方法;2. 通过自定义HTTPAdapter实现更灵活逻辑,如根据响应头或指数退避调整重试间隔;3. 还可创建完全自定义的重试类以获得最大灵活性。此外,Python中发送HTTP请求还可选择urllib3(底层灵活但API复杂)、aiohttp(异步高并发但学习曲线陡)、httpx(同步异步兼支持且功能强但生态较新)。处理HTTP状态码时可用response.raise_for_status()自动抛出异常,并结合try...except捕获不同错误,也可直接检查response.status_code属性执行特定处理逻辑。发送请求时设置代理可通过proxies参数指定各协议代理地址,HTTPS请求SSL验证默认开启,可设verify=False临时禁用(不推荐),最佳实践是将证书路径传给verify参数以保障安全。
在Python中发送HTTP请求,你需要借助一些库,比如requests
。处理请求超时和重试,关键在于设置合适的参数和编写异常处理逻辑。

import requests from requests.exceptions import Timeout, ConnectionError from urllib3.util.retry import Retry from requests.adapters import HTTPAdapter def send_http_request(url, params=None, data=None, headers=None, timeout=5, max_retries=3): """ 发送HTTP请求,并处理超时和重试。 Args: url (str): 请求的URL。 params (dict, optional): URL参数。Defaults to None. data (dict, optional): 请求体数据。Defaults to None. headers (dict, optional): 请求头。Defaults to None. timeout (int, optional): 超时时间(秒)。Defaults to 5. max_retries (int, optional): 最大重试次数。Defaults to 3. Returns: requests.Response: 响应对象,如果所有重试都失败,则返回None。 """ retry_strategy = Retry( total=max_retries, backoff_factor=1, # 重试间隔时间,单位秒,计算方式:{backoff factor} * (2 ** ({number of total retries} - 1)) status_forcelist=[429, 500, 502, 503, 504], # 哪些状态码需要重试 method_whitelist=["HEAD", "GET", "PUT", "DELETE", "OPTIONS", "TRACE", "POST"] # 哪些请求方法允许重试 ) adapter = HTTPAdapter(max_retries=retry_strategy) http = requests.Session() http.mount("https://", adapter) http.mount("http://", adapter) try: response = http.request( "POST" if data else "GET", # 根据是否有data来决定请求方式,这是一个简化 url, params=params, data=data, headers=headers, timeout=timeout ) response.raise_for_status() # 检查响应状态码,如果不是200,抛出异常 return response except Timeout: print(f"请求超时: {url}") return None except ConnectionError: print(f"连接错误: {url}") return None except requests.exceptions.HTTPError as e: print(f"HTTP错误: {e}") return None except Exception as e: print(f"发生未知错误: {e}") return None # 示例用法 if __name__ == '__main__': url = "https://www.example.com" response = send_http_request(url, timeout=2, max_retries=2) if response: print(f"请求成功,状态码: {response.status_code}") # print(f"响应内容: {response.text}") else: print("请求失败")
如何自定义重试策略?
除了使用urllib3.util.retry.Retry
,你还可以通过自定义requests.adapters.HTTPAdapter
来实现更灵活的重试策略。例如,你可以根据响应头中的信息来决定是否重试,或者使用指数退避算法来调整重试间隔。你甚至可以完全自定义一个重试类,实现自己的重试逻辑。这需要你深入理解requests
库的内部机制,但可以提供最大的灵活性。

import time import requests from requests.adapters import HTTPAdapter from requests.exceptions import ConnectionError, Timeout class CustomRetry(HTTPAdapter): def __init__(self, *args, **kwargs): self.max_retries = kwargs.pop('max_retries', 3) self.backoff_factor = kwargs.pop('backoff_factor', 0.5) super(CustomRetry, self).__init__(*args, **kwargs) def send(self, request, **kwargs): retries = 0 while True: try: response = super(CustomRetry, self).send(request, **kwargs) response.raise_for_status() # 检查状态码 return response except (ConnectionError, Timeout) as e: print(f"请求失败,正在重试 ({retries+1}/{self.max_retries}): {e}") if retries >= self.max_retries: raise # 达到最大重试次数,抛出异常 retries += 1 time.sleep(self.backoff_factor * (2 ** (retries - 1))) # 指数退避 except requests.exceptions.HTTPError as e: # 这里可以根据状态码判断是否重试,例如只重试500错误 if e.response.status_code == 500 and retries < self.max_retries: print(f"服务器错误,正在重试 ({retries+1}/{self.max_retries}): {e}") retries += 1 time.sleep(self.backoff_factor * (2 ** (retries - 1))) else: raise # 不重试,抛出异常 def close(self): super(CustomRetry, self).close() if __name__ == '__main__': session = requests.Session() retry_adapter = CustomRetry(max_retries=3, backoff_factor=0.5) session.mount('http://', retry_adapter) session.mount('https://', retry_adapter) try: response = session.get('https://www.example.com', timeout=5) print(f"请求成功,状态码: {response.status_code}") except Exception as e: print(f"请求失败: {e}")
除了requests库,还有其他选择吗?它们有什么优缺点?
当然,除了requests
,Python中还有其他发送HTTP请求的库,例如urllib3
(requests
的底层库)、aiohttp
(用于异步请求)和httpx
(支持同步和异步请求)。
urllib3
: 优点是底层、灵活,适合构建更高级的HTTP客户端。缺点是API相对复杂,需要手动处理很多细节。aiohttp
: 优点是基于asyncio,适合高并发的异步请求。缺点是学习曲线较陡峭,需要理解async/await的概念。httpx
: 优点是同时支持同步和异步请求,API设计更现代化,功能更强大。缺点是相对较新,生态不如requests
成熟。
选择哪个库取决于你的具体需求。如果只是简单的HTTP请求,requests
通常是最佳选择。如果需要处理大量并发请求,可以考虑aiohttp
或httpx
。如果需要对HTTP协议进行更底层的控制,urllib3
可能更适合。

如何处理不同的HTTP响应状态码?
处理HTTP响应状态码是构建健壮的HTTP客户端的关键。requests
库提供了一个方便的方法response.raise_for_status()
,它可以自动检查响应状态码,并在状态码表示错误时抛出异常。你可以在try...except
块中使用它来捕获和处理错误。
但是,有时候你需要根据不同的状态码采取不同的处理方式。例如,你可能希望在收到404错误时记录日志,或者在收到503错误时进行重试。这时,你可以直接检查response.status_code
属性,并根据它的值来执行不同的逻辑。
import requests def handle_response(response): if response.status_code == 200: print("请求成功") # 处理响应数据 elif response.status_code == 404: print("资源未找到") # 记录日志或采取其他措施 elif response.status_code == 503: print("服务不可用,稍后重试") # 实施重试策略 else: print(f"发生未知错误: {response.status_code}") response.raise_for_status() # 如果是不期望的状态码,仍然抛出异常
如何在发送请求时设置代理?
在某些情况下,你可能需要通过代理服务器发送HTTP请求。requests
库允许你通过proxies
参数来设置代理。你可以为不同的协议(例如HTTP和HTTPS)设置不同的代理。
import requests proxies = { "http": "http://10.10.1.10:3128", "https": "http://10.10.1.10:1080", } try: response = requests.get("https://www.example.com", proxies=proxies, timeout=5) response.raise_for_status() print("请求成功") except requests.exceptions.RequestException as e: print(f"请求失败: {e}")
请注意,代理服务器可能会影响请求的性能和安全性。确保你使用的代理是可信的,并且配置正确。此外,一些代理服务器可能需要身份验证。你可以在代理URL中包含用户名和密码,例如http://user:password@10.10.1.10:3128
。
如何处理HTTPS请求的SSL证书验证?
默认情况下,requests
库会验证HTTPS请求的SSL证书,以确保连接的安全性。如果服务器的证书无效或过期,requests
会抛出异常。
在某些情况下,你可能需要禁用SSL证书验证。例如,你可能正在连接到一个使用自签名证书的开发服务器。你可以通过设置verify=False
来禁用证书验证。但是,这会降低连接的安全性,因此应该谨慎使用。
import requests try: response = requests.get("https://self-signed.example.com", verify=False, timeout=5) response.raise_for_status() print("请求成功") except requests.exceptions.RequestException as e: print(f"请求失败: {e}")
更好的做法是,将服务器的证书添加到你的信任列表中。你可以通过设置verify
参数为证书文件的路径来实现。
import requests try: response = requests.get("https://example.com", verify="/path/to/certfile.pem", timeout=5) response.raise_for_status() print("请求成功") except requests.exceptions.RequestException as e: print(f"请求失败: {e}")
这可以确保连接的安全性,同时避免验证错误。
到这里,我们也就讲完了《Python发送HTTP请求及超时重试技巧》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于Http请求,超时重试的知识点!
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
459 收藏
-
286 收藏
-
444 收藏
-
352 收藏
-
324 收藏
-
180 收藏
-
123 收藏
-
365 收藏
-
401 收藏
-
250 收藏
-
476 收藏
-
470 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习