Python requests 超时机制与重试策略详解

巷口听风
巷口听风
发布时间:2026-10-13| 2人浏览过
原创

本文深入解析 Python requests 库中的超时处理机制,区分连接超时与读取超时的定义及默认行为。通过代码示例演示如何分别设置两种超时时间,并介绍利用 HTTPAdapter 配置最大重试次数(max_retries)的方法,帮助开发者避免爬虫程序因网络波动而永久挂起或频繁报错。

在进行网络请求时,超时问题是无法完全避免的。若在使用 requests 库时未显式配置超时参数,程序可能会陷入无限等待状态,导致永远无法获得响应。

超时机制主要包含两个维度:连接超时和读取超时。

连接超时

连接超时是指客户端尝试与远程服务器端口建立连接(即调用 connect() 方法)时,Request 库所等待的最大秒数。

import time
import requests

url = 'http://www.google.com.hk'

print(time.strftime('%Y-%m-%d %H:%M:%S'))
try:
  html = requests.get(url, timeout=5).text
  print('success')
except requests.exceptions.RequestException as e:
  print(e)

print(time.strftime('%Y-%m-%d %H:%M:%S'))

以访问被墙的网站 google 为例,由于无法建立连接,错误信息会明确提示 connect timeout(连接超时)。

2018-12-14 14:38:20 HTTPConnectionPool(host='www.google.com.hk', port=80): Max retries exceeded with url: / (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x00000000047F80F0>, 'Connection to www.google.com.hk timed out. (connect timeout=5)')) 2018-12-14 14:38:25

即使开发者未手动设置超时参数,requests 也会应用一个默认的连接超时时间。经测试,该默认值约为 21 秒。

读取超时

读取超时指的是客户端等待服务器发送数据的时间。具体而言,它是指客户端等待服务器发送字节之间的时间间隔;在绝大多数(99.9%)情况下,这等同于等待服务器发送第一个字节之前的时间。

简而言之,连接超时限制了从发起请求到连接建立之间的最大时长;而读取超时则限制了连接成功后,等待服务器返回响应数据的最大时长。

读取超时没有默认值。如果不进行设置,程序将一直处于等待状态。许多爬虫程序出现卡死且无报错信息的情况,往往就是由于未设置读取超时所致。

若为 timeout 参数指定单一数值,如下所示:

r = requests.get('https://github.com', timeout=5)

此时该 timeout 值将同时作为 connect 和 read 的超时时间。若需分别指定,则应传入一个元组:

r = requests.get('https://github.com', timeout=(3.05, 27))

黑板课爬虫闯关的第四关人为设置了 15 秒的响应等待时间,非常适合用来说明读取超时的效果。

import time
import requests

url_login = 'http://www.heibanke.com/accounts/login/?next=/lesson/crawler_ex03/'

session = requests.Session()
session.get(url_login)

token = session.cookies['csrftoken']
session.post(url_login, data={'csrfmiddlewaretoken': token, 'username': 'guliang21', 'password': '123qwe'})

print(time.strftime('%Y-%m-%d %H:%M:%S'))

url_pw = 'http://www.heibanke.com/lesson/crawler_ex03/pw_list/'
try:
  html = session.get(url_pw, timeout=(5, 10)).text
  print('success')
except requests.exceptions.RequestException as e:
  print(e)

print(time.strftime('%Y-%m-%d %H:%M:%S'))

错误信息中会显示 read timeout(读取超时)。

2018-12-14 15:20:47 HTTPConnectionPool(host='www.heibanke.com', port=80): Read timed out. (read timeout=10) 2018-12-14 15:20:57

超时重试

面对一般性超时,我们通常不会直接返回错误,而是配置一个包含三次重连的机制。

def gethtml(url):
  i = 0
  while i < 3:
    try:
      html = requests.get(url, timeout=5).text
      return html
    except requests.exceptions.RequestException:
      i += 1

实际上,requests 已经为我们封装好了相关功能(尽管代码量可能有所增加……)。

import time
import requests
from requests.adapters import HTTPAdapter

s = requests.Session()
s.mount('http://', HTTPAdapter(max_retries=3))
s.mount('https://', HTTPAdapter(max_retries=3))

print(time.strftime('%Y-%m-%d %H:%M:%S'))
try:
  r = s.get('http://www.google.com.hk', timeout=5)
  return r.text
except requests.exceptions.RequestException as e:
  print(e)
print(time.strftime('%Y-%m-%d %H:%M:%S'))

max_retries 参数用于设定最大重试次数。若设置为重试 3 次,加上最初的一次请求,总共将执行 4 次尝试。因此,上述代码的运行耗时约为 20 秒,而非单一的 15 秒。

2018-12-14 15:34:03 HTTPConnectionPool(host='www.google.com.hk', port=80): Max retries exceeded with url: / (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x0000000013269630>, 'Connection to www.google.com.hk timed out. (connect timeout=5)')) 2018-12-14 15:34:23

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。