详解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实现数通设备tftp备份配置文件示例
Apr 02 Python
快速入手Python字符编码
Aug 03 Python
python版学生管理系统
Jan 10 Python
python的re正则表达式实例代码
Jan 24 Python
解决Mac安装scrapy失败的问题
Jun 13 Python
python3使用SMTP发送简单文本邮件
Jun 19 Python
Python 利用scrapy爬虫通过短短50行代码下载整站短视频
Oct 29 Python
numpy 计算两个数组重复程度的方法
Nov 07 Python
python 实现查找文件并输出满足某一条件的数据项方法
Jun 12 Python
Python 取numpy数组的某几行某几列方法
Oct 24 Python
使用PyWeChatSpy自动回复微信拍一拍功能的实现代码
Jul 02 Python
Python定义一个Actor任务
Jul 29 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
2个Codeigniter文件批量上传控制器写法例子
2014/07/25 PHP
Ajax和PHP正则表达式验证表单及验证码
2016/09/24 PHP
CodeIgniter框架常见用法工作总结
2017/03/16 PHP
Mootools 1.2教程 滑动效果(Slide)
2009/09/15 Javascript
Jquery从头学起第四讲 jquery入门教程
2010/08/01 Javascript
从零开始学习jQuery (十一) 实战表单验证与自动完成提示插件
2011/02/23 Javascript
读JavaScript DOM编程艺术笔记
2011/11/15 Javascript
javascript管中窥豹 形参与实参浅析
2011/12/17 Javascript
用js将内容复制到剪贴板兼容浏览器
2014/03/18 Javascript
JavaScript检测实例属性, 原型属性
2015/02/04 Javascript
jQuery实现动态添加和删除一个div
2015/08/12 Javascript
AngularJS路由实现页面跳转实例
2017/03/03 Javascript
js实现一键复制功能
2017/03/16 Javascript
微信小程序 http请求的session管理
2017/06/07 Javascript
JScript实现地址选择功能
2017/08/15 Javascript
EasyUI框架 使用Ajax提交注册信息的实现代码
2017/09/27 Javascript
解决vue 中 echart 在子组件中只显示一次的问题
2018/08/07 Javascript
vscode调试node.js的实现方法
2020/03/22 Javascript
Vue+element+cookie记住密码功能的简单实现方法
2020/09/20 Javascript
python脚本实现查找webshell的方法
2014/07/31 Python
python 列表转为字典的两个小方法(小结)
2019/06/28 Python
pandas的相关系数与协方差实例
2019/12/27 Python
用sleep间隔进行python反爬虫的实例讲解
2020/11/30 Python
python进行二次方程式计算的实例讲解
2020/12/06 Python
英国在线自行车商店:Evans Cycles
2016/09/26 全球购物
Casetify官网:自制专属手机壳、iPad护壳和Apple Watch手表带
2018/05/09 全球购物
教师个人自我鉴定
2014/02/08 职场文书
班主任新年寄语
2014/04/04 职场文书
12.4全国法制宣传日活动总结
2014/11/01 职场文书
颐和园导游词
2015/01/30 职场文书
全陪导游词
2015/02/04 职场文书
2016年度创先争优活动总结
2016/04/05 职场文书
工作报告范文
2019/06/20 职场文书
python基础学习之生成器与文件系统知识总结
2021/05/25 Python
my.ini优化mysql数据库性能的十个参数(推荐)
2021/05/26 MySQL
vue如何实现关闭对话框后刷新列表
2022/04/08 Vue.js