详解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类的专用方法实例分析
Jan 09 Python
python 查找字符串是否存在实例详解
Jan 20 Python
利用python实现简单的循环购物车功能示例代码
Jul 05 Python
python判断一个集合是否为另一个集合的子集方法
May 04 Python
Python之列表实现栈的工作功能
Jan 28 Python
对python:threading.Thread类的使用方法详解
Jan 31 Python
python面试题小结附答案实例代码
Apr 11 Python
Python自动化运维之Ansible定义主机与组规则操作详解
Jun 13 Python
Python如何实现小程序 无限求和平均
Feb 18 Python
Python3使用xlrd、xlwt处理Excel方法数据
Feb 28 Python
Python GUI编程学习笔记之tkinter中messagebox、filedialog控件用法详解
Mar 30 Python
python中os.path.join()函数实例用法
May 26 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
日本十大最佳动漫,全都是二次元的神级作品
2019/10/05 日漫
php实现把url转换迅雷thunder资源下载地址的方法
2014/11/07 PHP
php实现模拟登陆方正教务系统抓取课表
2015/05/19 PHP
PHP后台实现微信小程序登录
2018/08/03 PHP
用js统计用户下载网页所需时间的脚本
2008/10/15 Javascript
ExtJS PropertyGrid中使用Combobox选择值问题
2010/06/13 Javascript
jsvascript图像处理—(计算机视觉应用)图像金字塔
2013/01/15 Javascript
javascript中创建对象的几种方法总结
2013/11/01 Javascript
javascript 实现子父窗体互相传值的简单实例
2014/02/17 Javascript
js获取鼠标点击的位置实现思路及代码
2014/05/09 Javascript
jquery向上向下取整适合分页查询
2014/09/06 Javascript
两种方法基于jQuery实现IE浏览器兼容placeholder效果
2014/10/14 Javascript
jquery渐隐渐显的图片幻灯闪烁切换实现方法
2015/02/26 Javascript
JavaScript是如何实现继承的(六种方式)
2016/03/31 Javascript
jQuery中deferred对象使用方法详解
2016/07/14 Javascript
js替换字符串中所有指定的字符(实现代码)
2016/08/17 Javascript
AngularJS实现select的ng-options功能示例
2017/07/12 Javascript
说说AngularJS中的$parse和$eval的用法
2017/09/14 Javascript
微信小程序生成海报分享朋友圈的实现方法
2019/05/06 Javascript
python通过post提交数据的方法
2015/05/06 Python
Python实现SVN的目录周期性备份实例
2015/07/17 Python
详解Python中的__getitem__方法与slice对象的切片操作
2016/06/27 Python
Ubuntu 下 vim 搭建python 环境 配置
2017/06/12 Python
解决使用PyCharm时无法启动控制台的问题
2019/01/19 Python
详解Python time库的使用
2019/10/10 Python
python反转列表的三种方式解析
2019/11/08 Python
Python散点图与折线图绘制过程解析
2019/11/30 Python
scrapy利用selenium爬取豆瓣阅读的全步骤
2020/09/20 Python
Python高阶函数与装饰器函数的深入讲解
2020/11/10 Python
python实现代码审查自动回复消息
2021/02/01 Python
SQL Server面试题
2016/10/17 面试题
股东合作协议书
2014/04/14 职场文书
销售经理岗位职责
2015/01/31 职场文书
工程部岗位职责范本
2015/04/11 职场文书
幼儿园师德师风心得体会
2016/01/12 职场文书
七年级写作指导之游记作文
2019/10/07 职场文书