详解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框架Flask下网站开发入门实例
Feb 08 Python
Django中模版的子目录与include标签的使用方法
Jul 16 Python
python实现识别相似图片小结
Feb 22 Python
基于Python实现一个简单的银行转账操作
Mar 06 Python
详解Ubuntu16.04安装Python3.7及其pip3并切换为默认版本
Feb 25 Python
Django REST framework 分页的实现代码
Jun 19 Python
pytorch动态网络以及权重共享实例
Jan 06 Python
Python while循环使用else语句代码实例
Feb 07 Python
浅谈在JupyterNotebook下导入自己的模块的问题
Apr 16 Python
python 常见的排序算法实现汇总
Aug 21 Python
Django drf请求模块源码解析
Jun 08 Python
一篇文章弄懂Python中的内建函数
Aug 07 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
DOTA2 6.87版本后新眼位详解攻略
2020/04/20 DOTA
php与php MySQL 之间的关系
2009/07/17 PHP
浅析ThinkPHP中的pathinfo模式和URL重写
2014/01/06 PHP
JavaScript 动态将数字金额转化为中文大写金额
2009/05/14 Javascript
使用nodejs、Python写的一个简易HTTP静态文件服务器
2014/07/18 NodeJs
JS+DIV实现鼠标划过切换层效果的方法
2015/05/25 Javascript
Javascript实现鼠标右键特色菜单
2015/08/04 Javascript
jquery插件jquery.LightBox.js实现点击放大图片并左右点击切换效果(附demo源码下载)
2016/02/25 Javascript
Jquery EasyUI实现treegrid上显示checkbox并取选定值的方法
2016/04/29 Javascript
jquery获取点击控件的绝对位置简单实例
2016/10/13 Javascript
JS经典正则表达式笔试题汇总
2016/12/15 Javascript
jQuery实现遍历复选框的方法示例
2017/03/06 Javascript
JavaScript正则表达式简单实用实例
2017/06/23 Javascript
解决html-jquery/js引用外部图片时遇到看不了或出现403的问题
2017/09/22 jQuery
Vue2.X和Vue3.0数据响应原理变化的区别
2019/11/07 Javascript
Antd-vue Table组件添加Click事件,实现点击某行数据教程
2020/11/17 Javascript
python通过BF算法实现关键词匹配的方法
2015/03/13 Python
Python网络编程中urllib2模块的用法总结
2016/07/12 Python
python使用xlrd与xlwt对excel的读写和格式设定
2017/01/21 Python
python写一个md5解密器示例
2018/02/23 Python
基于python实现的百度新歌榜、热歌榜下载器(附代码)
2019/08/05 Python
Python爬虫:将headers请求头字符串转为字典的方法
2019/08/21 Python
html5使用html2canvas实现浏览器截图的示例
2017/08/31 HTML / CSS
生产现场工艺工程师岗位职责
2013/11/28 职场文书
美容师的职业规划书
2013/12/27 职场文书
运动会入场式解说词
2014/02/18 职场文书
学历公证委托书
2014/04/09 职场文书
大学军训的体会
2014/11/08 职场文书
大连导游词
2015/02/12 职场文书
学校捐款活动总结
2015/05/09 职场文书
借款民事起诉状范文
2015/05/19 职场文书
英语演讲开场白
2015/05/29 职场文书
法制教育观后感
2015/06/17 职场文书
团队执行力培训心得体会
2015/08/15 职场文书
创业计划之特色精品店
2019/08/12 职场文书
《弟子规》读后感:知廉耻、明是非、懂荣辱、辨善恶
2019/12/03 职场文书