小白学 Python 爬虫(13):urllib 基础使用(三)

人生苦短,我用 Pythonhtml

前文传送门:python

小白学 Python 爬虫(1):开篇git

小白学 Python 爬虫(2):前置准备(一)基本类库的安装github

小白学 Python 爬虫(3):前置准备(二)Linux基础入门数据库

小白学 Python 爬虫(4):前置准备(三)Docker基础入门服务器

小白学 Python 爬虫(5):前置准备(四)数据库基础网络

小白学 Python 爬虫(6):前置准备(五)爬虫框架的安装框架

小白学 Python 爬虫(7):HTTP 基础socket

小白学 Python 爬虫(8):网页基础ide

小白学 Python 爬虫(9):爬虫基础

小白学 Python 爬虫(10):Session 和 Cookies

小白学 Python 爬虫(11):urllib 基础使用(一)

小白学 Python 爬虫(12):urllib 基础使用(二)

引言

前面两篇基础,咱们介绍请求发送的过程。

不知道各位同窗有没有想过这样一个问题,若是在爬虫运行的过程当中,网络忽然波动了下,好比忽然网速很慢很慢,形成当前的请求超时,程序极可能会直接挂掉。

这种处理方式显然不是咱们但愿看到的,咱们但愿看到的确定是若是当前的请求挂掉,那就挂掉,不要影响其余的请求或者是下一次的请求。

那么,咱们在发送请求的时候,异常处理就显得十分有必要。

urllib 的 error 模块定义了由 request 模块产生的异常,若是出现问题, request 模块便会抛出 error 模块中定义的异常。

URLError

URLError 这个类来自于 urllib 库的 error 模块,它继承自 OSError ,是 error 异常模块的基类,由 request 模块产生的异常均可以经过捕获这个类来处理。

它只有一个属性 reason ,即返回错误的缘由。

咱们来写一个简单的示例你们看一下:

from urllib import request, error

# 访问明显不存在的地址,报错:Not Found
try:
    response = request.urlopen('https://www.geekdigging.com/aa')
except error.URLError as e:
    print(e.reason)

# 访问超时,报错:timed out
try:
    response = request.urlopen('https://www.baidu.com', timeout=0.001)
except error.URLError as e:
    print(e.reason)复制代码

这里咱们访问了一个明显不存在的连接和限定了极短的超时时间,这里会抛出异常,可是咱们捕获了 URLError 这个异常,运行结果以下:

Not Found
timed out复制代码

程序没有直接抛出异常终止运行,而是输出了上面这个异常,经过这样的操做,咱们能够避免程序异常终止,同时还能够对这个异常作出针对性的处理。

此外,异常捕捉抛出的异常不必定都是字符串类型,好比访问超时的报错,咱们将打印结果的代码稍做改动:

from urllib import request, error
import socket

# 异常类型示例
try:
    response = request.urlopen('https://www.baidu.com', timeout=0.001)
except error.URLError as e:
    print(type(e.reason))
    if isinstance(e.reason, socket.timeout):
        print('TIME OUT')复制代码

结果以下:

<class 'socket.timeout'>
TIME OUT复制代码

HTTPError

它是 URLError 的子类,专门用来处理 HTTP 请求错误,好比认证请求失败等。它有以下 3 个属性。

  • code:返回HTTP状态码,好比404表示网页不存在,500表示服务器内部错误等。
  • reason:同父类同样,用于返回错误的缘由。
  • headers:返回请求头。

仍是先看一个最简单的示例:

from urllib import request, error

# 访问明显不存在的地址,使用 HTTPError 捕捉异常
try:
    response = request.urlopen('https://www.geekdigging.com/aa')
except error.HTTPError as e:
    print(e.reason, e.code, e.headers, sep='\n')复制代码

运行结果以下:

Not Found
404
Date: Sun, 01 Dec 2019 15:11:48 GMT
Content-Type: text/html
Content-Length: 49307
Connection: close
Server: tencent-cos
Last-Modified: Sun, 01 Dec 2019 15:03:24 GMT
X-NWS-UUID-VERIFY: c89959eb27b89a0fb1c0326d1b2e7171
Accept-Ranges: bytes
ETag: "1bb6cc2c28a5621cf0c3238107edc229"
x-cos-error-code: NoSuchKey
x-cos-error-detail-Key: aa
x-cos-error-message: The specified key does not exist.
x-cos-request-id: NWRlM2Q4MzRfMzNhNzAzMDlfYTljZl8yNGU1NTgx
x-cos-trace-id: OGVmYzZiMmQzYjA2OWNhODk0NTRkMTBiOWVmMDAxODc0OWRkZjk0ZDM1NmI1M2E2MTRlY2MzZDhmNmI5MWI1OTQ5YWUxMjNkYTk3NzdjZmZlMDQzOTgxOThkOTNlOWFkOGJiN2YzOGQ5MDdjNGY0ODQ1MGIzYjUyMzg2NjFhNzc=
X-Daa-Tunnel: hop_count=2
X-NWS-LOG-UUID: 7c3fe80b-af9a-4e59-969b-10c8b3963a1d
X-Cache-Lookup: Hit From Upstream
X-Cache-Lookup: Hit From Upstream复制代码

由于 URLError 是 HTTPError 的父类,因此能够先选择捕获子类的错误,再去捕获父类的错误,这样对异常的处理更具针对性。

注意: 捕捉异常通常先捕捉子类异常,再捕捉父类异常。

因此咱们能够更改下前面的异常捕捉的代码进行一些优化:

# 优化异常捕捉代码
try:
    response = request.urlopen('https://www.geekdigging.com/aa')
except error.HTTPError as e:
    print(e.reason, e.code, e.headers, sep='\n')
except error.URLError as e:
    print(e.reason)
else:
    print('Request Success!')复制代码

示例代码

本系列的全部代码小编都会放在代码管理仓库 Github 和 Gitee 上,方便你们取用。

示例代码-Github

示例代码-Gitee

参考

https://www.cnblogs.com/zhangxinqi/p/9170312.html

若是个人文章对您有帮助,请扫码关注下做者的公众号:获取最新干货推送:)
相关文章
相关标签/搜索