详解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使用xauth方式登录饭否网然后发消息
Apr 11 Python
Python实现把xml或xsl转换为html格式
Apr 08 Python
python动态参数用法实例分析
May 25 Python
快速实现基于Python的微信聊天机器人示例代码
Mar 03 Python
python实现闹钟定时播放音乐功能
Jan 25 Python
python 实现调用子文件下的模块方法
Dec 07 Python
Python3.5文件读与写操作经典实例详解
May 01 Python
Python对接 xray 和微信实现自动告警
Sep 17 Python
Python递归实现打印多重列表代码
Feb 27 Python
使用keras实现孪生网络中的权值共享教程
Jun 11 Python
Pytorch 扩展Tensor维度、压缩Tensor维度的方法
Sep 09 Python
Python数据分析入门之数据读取与存储
May 13 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启用zlib压缩文件的配置方法
2013/06/12 PHP
php实现图片缩放功能类
2013/12/18 PHP
php数组中包含中文的排序方法
2014/06/03 PHP
PDO防注入原理分析以及使用PDO的注意事项总结
2014/10/23 PHP
Yii框架中memcache用法实例
2014/12/03 PHP
PHP积分兑换接口实例
2015/02/09 PHP
PHP中用mysqli面向对象打开连接关闭mysql数据库的方法
2016/11/05 PHP
详谈php ip2long 出现负数的原因及解决方法
2017/04/05 PHP
js中substr,substring,indexOf,lastIndexOf,split,replace的用法详解
2015/11/09 Javascript
JavaScript中的await/async的作用和用法
2016/10/31 Javascript
JS常用算法实现代码
2016/11/14 Javascript
JavaScript中this的用法及this在不同应用场景的作用解析
2017/04/13 Javascript
JavaScript实现简单动态进度条效果
2018/04/06 Javascript
浅谈Vue组件及组件的注册方法
2018/08/24 Javascript
JavaScript实现预览本地上传图片功能完整示例
2019/03/08 Javascript
vue微信分享的实现(在当前页面分享其他页面)
2019/04/16 Javascript
AjaxFileUpload.js实现异步上传文件功能
2019/04/19 Javascript
微信小程序实现单列下拉菜单效果
2019/04/25 Javascript
原生JS实现图片懒加载之页面性能优化
2019/04/26 Javascript
详解在IDEA中将Echarts引入web两种方式(使用js文件和maven的依赖导入)
2020/07/11 Javascript
js面试题之异步问题的深入理解
2020/09/20 Javascript
python 提取文件的小程序
2009/07/29 Python
Python3.5编程实现修改IIS WEB.CONFIG的方法示例
2017/08/18 Python
Django实现表单验证
2018/09/08 Python
python通过txt文件批量安装依赖包的实现步骤
2019/08/13 Python
Python中__repr__和__str__区别详解
2019/11/07 Python
HTML5新增的8类INPUT输入类型介绍
2015/07/06 HTML / CSS
使用HTML5和CSS3制作一个模态框的示例
2018/03/07 HTML / CSS
英国女性时尚精品店:THE DRESSING ROOM
2018/05/23 全球购物
都柏林通行卡/城市通票:The Dublin Pass
2020/02/16 全球购物
大学生标准推荐信范文
2013/11/25 职场文书
小学课外活动总结
2014/07/09 职场文书
2014全年工作总结
2014/11/27 职场文书
公司文体活动总结
2015/05/07 职场文书
小学运动会通讯稿
2015/07/18 职场文书
教你怎么用Python实现多路径迷宫
2021/04/29 Python