详解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设计模式之访问者模式
Nov 18 Python
通过Python实现自动填写调查问卷
Sep 06 Python
Python实现针对给定字符串寻找最长非重复子串的方法
Apr 21 Python
Python常用字符串替换函数strip、replace及sub用法示例
May 21 Python
Python按钮的响应事件详解
Mar 04 Python
Python使用itchat 功能分析微信好友性别和位置
Aug 05 Python
pywinauto自动化操作记事本
Aug 26 Python
使用Python实现画一个中国地图
Nov 23 Python
python将字典内容写入json文件的实例代码
Aug 12 Python
python 爬虫请求模块requests详解
Dec 04 Python
python实现定时发送邮件
Dec 23 Python
浅谈Python实现opencv之图片色素的数值运算和逻辑运算
Jun 23 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
dedecms系统常用术语汇总
2007/04/03 PHP
PHP用strstr()函数阻止垃圾评论(通过判断a标记)
2013/09/28 PHP
Joomla开启SEF的方法
2016/05/04 PHP
在云虚拟主机部署thinkphp5项目的步骤详解
2017/12/21 PHP
JavaScript实现网页上的浮动广告的简单方法
2013/06/14 Javascript
js实现页面跳转的几种方法小结
2016/05/16 Javascript
15款最好的Bootstrap在线编辑器
2016/08/03 Javascript
JS实现弹出下载对话框及常见文件类型的下载
2017/07/13 Javascript
使用yeoman构建angular应用的方法
2017/08/14 Javascript
three.js 将图片马赛克化的示例代码
2020/07/31 Javascript
jQuery实现移动端扭蛋机抽奖
2020/11/08 jQuery
Python中捕捉详细异常信息的代码示例
2014/09/18 Python
详解python单例模式与metaclass
2016/01/15 Python
Python判断值是否在list或set中的性能对比分析
2016/04/16 Python
Python中functools模块函数解析
2017/03/12 Python
pandas将DataFrame的列变成行索引的方法
2018/04/10 Python
Python unittest单元测试框架总结
2018/09/08 Python
对python For 循环的三种遍历方式解析
2019/02/01 Python
python装饰器简介---这一篇也许就够了(推荐)
2019/04/01 Python
Win10用vscode打开anaconda环境中的python出错问题的解决
2020/05/25 Python
详解python的变量缓存机制
2021/01/24 Python
英国第一蛋白粉品牌:Myprotein
2016/09/14 全球购物
全球虚拟主机商:HostGator
2017/02/06 全球购物
洛佩桑酒店官方网站:Lopesan Hotels
2019/04/15 全球购物
贝佳斯官方网站:Borghese
2020/05/08 全球购物
十佳班主任事迹材料
2014/01/18 职场文书
汽车专业学生自我评价
2014/01/19 职场文书
工艺员岗位职责
2014/02/11 职场文书
幼儿园中班下学期评语
2014/04/18 职场文书
小学学雷锋活动总结
2014/04/25 职场文书
养成教育工作总结
2015/08/13 职场文书
幼儿教师继续教育培训心得体会
2016/01/19 职场文书
祝福语集锦:朋友新店开业祝福语
2019/12/10 职场文书
Django REST framework 限流功能的使用
2021/06/24 Python
Redis集群的关闭与重启操作
2021/07/07 Redis
Spring Boot项目传参校验的最佳实践指南
2022/04/05 Java/Android