网络请求不可避免会遇上请求超时的情况,在 requests 中,如果不设置你的程序可能会永远失去响应。
错误与异常
遇到网络问题(如:DNS 查询失败、拒绝连接等)时,Requests 会抛出一个 ConnectionError 异常。
如果 HTTP 请求返回了不成功的状态码, Response.raise_for_status() 会抛出一个 HTTPError 异常。
若请求超时,则抛出一个 Timeout 异常。
若请求超过了设定的最大重定向次数,则会抛出一个 TooManyRedirects 异常。
所有Requests显式抛出的异常都继承自 requests.exceptions.RequestException
具体的异常实例可以去查询文档。
HTTP异常
HTTP异常需要手动抛出:
Response.raise_for_status()
此方法在状态码为200以外抛出一个HTTPError异常
HTTPError.response.status_code获取状态码
requests模块内置异常类的层次结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| IOError +-- RequestException # 处理不确定的异常请求 +-- HTTPError # HTTP错误 +-- ConnectionError # 连接错误 | +-- ProxyError # 代理错误 | +-- SSLError # SSL错误 | +-- ConnectTimeout(+-- Timeout) # (双重继承,下同)尝试连接到远程服务器时请求超时,产生此错误的请求可以安全地重试。 +-- Timeout # 请求超时 | +-- ReadTimeout # 服务器未在指定的时间内发送任何数据 +-- URLRequired # 发出请求需要有效的URL +-- TooManyRedirects # 重定向太多 +-- MissingSchema(+-- ValueError) # 缺少URL架构(例如http或https) +-- InvalidSchema(+-- ValueError) # 无效的架构,有效架构请参见defaults.py +-- InvalidURL(+-- ValueError) # 无效的URL | +-- InvalidProxyURL # 无效的代理URL +-- InvalidHeader(+-- ValueError) # 无效的Header +-- ChunkedEncodingError # 服务器声明了chunked编码但发送了一个无效的chunk +-- ContentDecodingError(+-- BaseHTTPError) # 无法解码响应内容 +-- StreamConsumedError(+-- TypeError) # 此响应的内容已被使用 +-- RetryError # 自定义重试逻辑失败 +-- UnrewindableBodyError # 尝试倒回正文时,请求遇到错误 +-- FileModeWarning(+-- DeprecationWarning) # 文件以文本模式打开,但Requests确定其二进制长度 +-- RequestsDependencyWarning # 导入的依赖项与预期的版本范围不匹配 Warning +-- RequestsWarning # 请求的基本警告
|
在爬虫中捕获异常
客户端timeout 秒内从基础套接字上必须接收到第一个字节的数据, 否则抛出超时异常。
timeout 设置单一的值,将会用作 connect 和 read 二者的 timeout。
如果需要让 request 永远等待,则传入一个 None 作为 timeout 的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| def askUrl(url): headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3775.400 QQBrowser/10.6.4208.400' } while(True): try: resp = requests.get(url=url, headers=headers, timeout=5) resp.raise_for_status() return resp except requests.HTTPError as error: print('失败状态码:%s' % (error)) break except requests.exceptions.RequestException as error: print('错误:%s\n重试...' % (error))
|