详解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复制文件代码实现
Dec 23 Python
详解Python中的strftime()方法的使用
May 22 Python
pandas进行数据的交集与并集方式的数据合并方法
Jun 27 Python
Python+OpenCV图片局部区域像素值处理改进版详解
Jan 23 Python
python面试题Python2.x和Python3.x的区别
May 28 Python
django 使用 PIL 压缩图片的例子
Aug 16 Python
win10子系统python开发环境准备及kenlm和nltk的使用教程
Oct 14 Python
python GUI库图形界面开发之PyQt5不规则窗口实现与显示GIF动画的详细方法与实例
Mar 09 Python
Python中免验证跳转到内容页的实例代码
Oct 23 Python
使用gunicorn部署django项目的问题
Dec 30 Python
python绕过图片滑动验证码实现爬取PTA所有题目功能 附源码
Jan 06 Python
Pandas数据类型之category的用法
Jun 28 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 dirname()与__FILE__常量的应用
2013/06/24 PHP
分享十款最出色的PHP安全开发库中文详细介绍
2015/03/22 PHP
php 中phar包的使用教程详解
2018/10/26 PHP
Laravel框架下的Contracts契约详解
2020/03/17 PHP
判断目标是否是window,document,和拥有tagName的Element的代码
2010/05/31 Javascript
14款经典网页图片和文字特效的jQuery插件-前端开发必备
2015/08/25 Javascript
jquery dataTable 获取某行数据
2017/05/05 jQuery
NodeJs form-data格式传输文件的方法
2017/12/13 NodeJs
ES6中Symbol、Set和Map用法详解
2019/08/20 Javascript
使用layui监听器监听select下拉框,事件绑定不成功的解决方法
2019/09/28 Javascript
vue 动态添加class,三个以上的条件做判断方式
2020/11/02 Javascript
python在Windows下安装setuptools(easy_install工具)步骤详解
2016/07/01 Python
python数据预处理之将类别数据转换为数值的方法
2017/07/05 Python
Python3 导入上级目录中的模块实例
2019/02/16 Python
Django框架首页和登录页分离操作示例
2019/05/28 Python
如何实现Django Rest framework版本控制
2019/07/25 Python
selenium+PhantomJS爬取豆瓣读书
2019/08/26 Python
PyTorch 解决Dataset和Dataloader遇到的问题
2020/01/08 Python
python小程序基于Jupyter实现天气查询的方法
2020/03/27 Python
解决django xadmin主题不显示和只显示bootstrap2的问题
2020/03/30 Python
用python实现前向分词最大匹配算法的示例代码
2020/08/06 Python
css3模拟jq点击事件的实例代码
2017/07/06 HTML / CSS
canvas粒子动画背景的实现示例
2018/09/03 HTML / CSS
马来西亚户外装备商店:PTT Outdoor
2019/07/13 全球购物
XML文档面试题
2015/08/05 面试题
Linux机考试题
2015/10/16 面试题
J2EE的优越性主要表现在哪些方面
2016/03/28 面试题
师范应届生求职信
2013/11/15 职场文书
幼教个人求职信范文
2013/12/02 职场文书
村容村貌整治方案
2014/05/21 职场文书
保密工作承诺书
2014/08/29 职场文书
党员干部观看《周恩来四个昼夜》思想汇报
2014/09/10 职场文书
2015年酒店客房部工作总结
2015/04/25 职场文书
2015年管理人员工作总结
2015/05/13 职场文书
2015年机关后勤工作总结
2015/05/26 职场文书
2015大学生暑期实习报告
2015/07/13 职场文书