详解Python requests 超时和重试的方法


Posted in Python onDecember 18, 2018

网络请求不可避免会遇上请求超时的情况,在 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

就算不设置,也会有一个默认的连接超时时间(我测试了下,大概是21秒)。

读取超时

读取超时指的就是客户端等待服务器发送请求的时间。(特定地,它指的是客户端要等待服务器发送字节之间的时间。在 99.9% 的情况下这指的是服务器发送第一个字节之前的时间)。

简单的说,连接超时就是发起请求连接到连接建立之间的最大时长,读取超时就是连接成功开始到服务器返回响应之间等待的最大时长。

读取超时是没有默认值的,如果不设置,程序将一直处于等待状态。 我们的爬虫经常卡死又没有任何的报错信息,原因就在这里了。

如果你设置了一个单一的值作为 timeout,如下所示:

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

这一 timeout 值将会用作 connect 和 read 二者的 timeout。如果要分别制定,就传入一个元组:

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 相关文章推荐
Python中的__SLOTS__属性使用示例
Feb 18 Python
浅谈python中截取字符函数strip,lstrip,rstrip
Jul 17 Python
python中numpy.zeros(np.zeros)的使用方法
Nov 07 Python
python模拟事件触发机制详解
Jan 19 Python
python实现简易版计算器
Jun 22 Python
10招!看骨灰级Pythoner玩转Python的方法
Apr 15 Python
Pandas库之DataFrame使用的学习笔记
Jun 21 Python
python多线程同步之文件读写控制
Feb 25 Python
pytorch载入预训练模型后,实现训练指定层
Jan 06 Python
python各层级目录下import方法代码实例
Jan 20 Python
python基础学习之递归函数知识总结
May 26 Python
Django中session进行权限管理的使用
Jul 09 Python
解决新django中的path不能使用正则表达式的问题
Dec 18 #Python
python 获取url中的参数列表实例
Dec 18 #Python
python 函数内部修改外部变量的方法
Dec 18 #Python
Python实现获取汉字偏旁部首的方法示例【测试可用】
Dec 18 #Python
python监测当前联网状态并连接的实例
Dec 18 #Python
Python实现繁体中文与简体中文相互转换的方法示例
Dec 18 #Python
解决python3 pika之连接断开的问题
Dec 18 #Python
You might like
PHP中路径问题的解决方案
2006/10/09 PHP
Yii调试SQL的常用方法
2014/07/09 PHP
php异步:在php中使用fsockopen curl实现类似异步处理的功能方法
2016/12/10 PHP
PHP实现的pdo连接数据库并插入数据功能简单示例
2019/03/30 PHP
jQuery 1.5最新版本的改进细节分析
2011/01/19 Javascript
JavaScript高级程序设计 事件学习笔记
2011/09/10 Javascript
无缝滚动js代码通俗易懂(自写)
2013/06/19 Javascript
jquery实现相册一下滑动两次的方法
2015/02/09 Javascript
jQuery实现行文字链接提示效果的方法
2015/03/10 Javascript
JS中setTimeout的巧妙用法前端函数节流
2016/03/24 Javascript
JavaScript中的this引用(推荐)
2016/08/05 Javascript
JS实现颜色动态淡化效果
2017/03/06 Javascript
javascript高级模块化require.js的具体使用方法
2017/10/31 Javascript
解决vue处理axios post请求传参的问题
2018/03/05 Javascript
详解js的视频和音频采集
2018/08/09 Javascript
通过实例学习React中事件节流防抖
2019/06/17 Javascript
Python MD5文件生成码
2009/01/12 Python
python实现绘制树枝简单示例
2014/07/24 Python
利用Python的Django框架中的ORM建立查询API
2015/04/20 Python
pyspark.sql.DataFrame与pandas.DataFrame之间的相互转换实例
2018/08/02 Python
利用Python将数值型特征进行离散化操作的方法
2018/11/06 Python
解决新django中的path不能使用正则表达式的问题
2018/12/18 Python
Python识别快递条形码及Tesseract-OCR使用详解
2019/07/15 Python
python3.6+django2.0+mysql搭建网站过程详解
2019/07/24 Python
Python 爬虫实现增加播客访问量的方法实现
2019/10/31 Python
解决django接口无法通过ip进行访问的问题
2020/03/27 Python
美国肌肉和力量商店:Muscle & Strength
2019/06/22 全球购物
Footshop法国:购买运动鞋
2020/01/19 全球购物
数控技术专业推荐信
2013/11/01 职场文书
计算机毕业生自荐信范文
2014/03/23 职场文书
法人授权委托书范本
2014/09/17 职场文书
军人离婚协议书样本
2014/10/21 职场文书
计划生育诚信协议书
2014/11/02 职场文书
党的群众路线教育实践活动个人对照检查材料(乡镇)
2014/11/05 职场文书
获奖感言一句话
2015/07/31 职场文书
MySQL的prepare使用以及遇到的bug
2022/05/11 MySQL