详解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的web框架编写前端模版的教程
Apr 30 Python
python 实现红包随机生成算法的简单实例
Jan 04 Python
python绘制铅球的运行轨迹代码分享
Nov 14 Python
python中的内置函数max()和min()及mas()函数的高级用法
Mar 29 Python
python dataframe astype 字段类型转换方法
Apr 11 Python
利用pandas将numpy数组导出生成excel的实例
Jun 14 Python
python实现画一颗树和一片森林
Jun 25 Python
python实现对csv文件的列的内容读取
Jul 04 Python
python 通过类中一个方法获取另一个方法变量的实例
Jan 22 Python
python打包成so文件过程解析
Sep 28 Python
基于Python中isfile函数和isdir函数使用详解
Nov 29 Python
pytorch中nn.Conv1d的用法详解
Dec 31 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更新mysql后获取影响的行数发生异常解决方法
2013/03/28 PHP
JS 容错处理代码, 屏蔽错误信息
2021/03/09 Javascript
用js实现输入提示(自动完成)的实例代码
2013/06/14 Javascript
让网页跳转到指定位置的jquery代码非书签
2013/09/06 Javascript
jquery遍历select元素(实例讲解)
2013/12/31 Javascript
JS+CSS实现可以凹陷显示选中单元格的方法
2015/03/02 Javascript
javascript操作Cookie(设置、读取、删除)方法详解
2015/03/18 Javascript
JavaScript实现iframe自动高度调整和不同主域名跨域
2016/02/27 Javascript
详解Angularjs中的依赖注入
2016/03/11 Javascript
jQuery技巧之让任何组件都支持类似DOM的事件管理
2016/04/05 Javascript
nodejs multer实现文件上传与下载
2017/05/10 NodeJs
js canvas实现放大镜查看图片功能
2017/06/08 Javascript
基于iScroll实现下拉刷新和上滑加载效果
2017/07/18 Javascript
极简主义法编写JavaScript类
2017/11/02 Javascript
Angular实现搜索框及价格上下限功能
2018/01/19 Javascript
vue父组件点击触发子组件事件的实例讲解
2018/02/08 Javascript
jQuery实现合并表格单元格中相同行操作示例
2019/01/28 jQuery
详解vue2.6插槽更新v-slot用法总结
2019/03/09 Javascript
Vue.js轮播图走马灯代码实例(全)
2019/05/08 Javascript
微信小程序背景音乐开发详解
2019/12/12 Javascript
原生JS实现留言板功能
2020/02/08 Javascript
[29:10]Ti4 冒泡赛第二天 NEWBEE vs Titan 3
2014/07/15 DOTA
Cpy和Python的效率对比
2015/03/20 Python
用Python编写一个简单的FUSE文件系统的教程
2015/04/02 Python
在Python 3中实现类型检查器的简单方法
2015/07/03 Python
Python中几种导入模块的方式总结
2017/04/27 Python
把django中admin后台界面的英文修改为中文显示的方法
2019/07/26 Python
春节到了 教你使用python来抢票回家
2020/01/06 Python
华为C++笔试题
2014/08/05 面试题
Prototype是怎么扩展DOM的
2014/10/01 面试题
材料采购员岗位职责
2013/12/17 职场文书
小学生学雷锋演讲稿
2014/04/25 职场文书
电工技术比武方案
2014/05/11 职场文书
博士生求职信
2014/07/06 职场文书
财会专业大学生求职信
2014/09/26 职场文书
用Python进行栅格数据的分区统计和批量提取
2021/05/27 Python