标题:Python之异常处理方法
文章目录
一、什么是异常?
首先,异常是一个事件,该事件会在程序执行过程中发生,并且会影响程序的正常运行。一般情况下,在Python解释器无法正常处理程序时就会发生一个异常。
同时,异常也是Python的一个对象,表示了一个错误。
当Python的脚本运行发生异常时我们需要捕获并且处理它,否则,程序就会终止运行。
二、常用的python标准异常
异常名称 | 异常描述 |
---|---|
BaseException | 所有异常的基类 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
AttributeError | 对象没有这个属性 |
IOError | 输入/输出操作失败 |
ImportError | 导入模块/对象失败 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
NameError | 未声明/初始化对象 (没有属性) |
RuntimeError | 一般的运行时错误 |
SyntaxError | Python 语法错误 |
IndentationError | 缩进错误 |
ValueError | 传入无效的参数 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |
URLError | 没有网络连接(没有路由到特定服务器),或者服务器不存在 |
HTTPError | 状态码指出服务器无法完成请求 |
AttributeError | 该对象没有指定的属性 |
三、另附HTTP状态码
状态码 | 状态码描述 |
---|---|
200 | 请求成功 处理方式:获得响应的内容,进行处理 |
201 | 请求完成,结果是创建了新资源。新创建资源的URI可在响应的实体中得到 处理方式:爬虫中不会遇到 |
202 | 请求被接受,但处理尚未完成 处理方式:阻塞等待 |
204 | 服务器端已经实现了请求,但是没有返回新的信 息。如果客户是用户代理,则无须为此更新自身的文档视图。 处理方式:丢弃 |
300 | 该状态码不被HTTP/1.0的应用程序直接使用, 只是作为3XX类型回应的默认解释。存在多个可用的被请求资源。 处理方式:若程序中能够处理,则进行进一步处理,如果程序中不能处理,则丢弃 |
301 | 请求到的资源都会分配一个永久的URL,这样就可以在将来通过该URL来访问此资源 处理方式:重定向到分配的URL |
302 | 请求到的资源在一个不同的URL处临时保存 处理方式:重定向到临时的URL |
304 | 请求的资源未更新 处理方式:丢弃 |
400 | 非法请求 处理方式:丢弃 |
401 | 未授权 处理方式:丢弃 |
403 | 禁止 处理方式:丢弃 |
404 | 没有找到 处理方式:丢弃 |
5XX | 回应代码以“5”开头的状态码表示服务器端发现自己出现错误,不能继续执行请求 处理方式:丢弃 |
四、异常处理语法
捕捉异常可以使用try/except语句。
try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
1、方法1
try / except / else
try:
<语句> # 尝试运行的代码
except <异常名字>:
<语句> # 如果在try部份引发了<异常名字>异常
或者:
(except <异常名字>,<数据>:
<语句> # 如果引发了<异常名字>异常,获得附加的<数据>)
else:
<语句> # 如果没有异常发生执行该语句
2、方法2
try / except / else
try:
<语句> # 尝试运行的代码
except:
<语句>
else:
<语句> # 如果没有异常执行这块代码
3、方法3
try / finally
try:
<语句>
finally:
<语句> # 退出try时总会执行
五、异常处理举例
举例1:ZeroDivisionError
a_number = float(input("please input a number :"))
try:
result = 100 / a_number
except ZeroDivisionError:
print( f'ERROR, the error is {ZeroDivisionError}')
else:
new_result = a_number / 100 + 100 / a_number
print("new_result", new_result)
finally:
print(a_number)
运行结果展示:
(这里是在 jupyter notebook 上面运行的)
图1:正常
图2:异常
举例2:AttributeError
import numpy as np
# 导入numpy模块
import pandas as pd
# 导入pandas模块
arr_0 = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11]])
# 用 numpy 模块生成一个数组
dict_0 = {
'a': [0, 1, 2, 3],
'b': [4, 5, 6, 7],
'c': [8, 9, 10, 11]
}
# 生成一个字典
df_0 = pd.DataFrame(data=dict_0, index=['a', 'b', 'c', 'd'])
# 生成一个 DataFrame 对象
print(arr_0)
# 打印数组
print(df_0)
# 打印 DataFrame 对象
print()
# 异常处理1:
try:
list_1 = arr_0.loc[2]
except AttributeError:
print('ERROR !', f'the error is {AttributeError}')
else:
print(list_1)
for j in list_1:
print(j)
finally:
print('异常处理1')
print()
# 异常处理2:
try:
list_2 = df_0.loc['b']
except AttributeError:
print('ERROR !', f'the error is {AttributeError}')
else:
print(list_2)
for i in list_2:
print(i)
finally:
print('异常处理2')
print()
print('END !')
# output>
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
a b c
a 0 4 8
b 1 5 9
c 2 6 10
d 3 7 11
ERROR ! the error is <class 'AttributeError'>
异常处理1
a 1
b 5
c 9
Name: b, dtype: int64
1
5
9
异常处理2
END !
运行结果的图片展示:
(这里还是使用了 jupyter notebook 来进行测试的)
代码:
结果:
举例3:UnicodeError
(这是Unicode 相关的错误,包括了:解码、编码时可能出现的错误)
我在曾经爬虫获取到数据以后,想把他们写进文档中,结果常常会出现编码错误,所以在此处,我们更加详细的介绍一下这个编码错误(UnicodeError),并通过爬虫来进行举例,因为爬虫中往往也会涉及到字符编码的转换等问题。
1、字符编码相关知识
1、GBK :汉字编码。
2、Big5 :繁体汉字编码,中国台湾等地区使用。
3、GB18030:收录了70244个汉字和字符,更加全面,与 GB2312-1980 和 GBK 兼容。
GB18030还支持少数民族的汉字,也包含了繁体汉字和日韩汉字。
4、ASCII:美国信息交换标准代码。
5、Unicode字符集:万国码。
严格的讲,Unicode不是一种编码,而是一个字符集。
6、UTF-8 :是Unicode的一种实现方法。
此外,还有, UTF-16,UTF-32等。
Python解决编码问题时,是下述流程:
decode解码 -------------------------- encode编码
str ---------> str(Unicode,byte类型) ---------> str
语法例如:
bytes.decode(encoding=“utf-8”, errors=“strict”)
str.encode(encoding=“utf-8”, errors=“strict”)
bytes.decode(encoding=“utf-8”, errors=“strict”)
str.encode(encoding=“utf-8”, errors=“strict”)
2、爬虫实例
这里其实我们可以不用异常处理,因为我们是可以提前了解到网页的编码的,这个可以从网页源码界面来进行查看,源代码中是会直接显示使用 ‘gbk’ 还是 ‘utf-8’ 还是别的什么编码来写的。
因此,只要我们提前查看了编码,那么我们就可以直接写出如何解码、如何编码,从而不必去异常处理了,这里写出来主要是要提醒大家有这么样的一个问题存在的。
因而,爬取网站之前,一定要查看网页源码的编码是什么。
原本想找一个用GBK编码的网站,但是找了半天都没有找到,只能用这个UTF-8的编码网站来进行实例了。
在此处我们爬取一个旅游网站的酒店预定网站地址,采用了requests模块,还有re模块。
import requests
import re
url = 'https://flights.ctrip.com/international/search/domestic?allianceid=564348&sid=3854334'
# 网址
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36 Edg/89.0.774.54'
}
# 请求头
response = requests.get(url=url, headers=headers).text
# 获取文本
response_1 = response.encode(encoding="utf-8", errors="strict")
# 先解码
response_2 = response_1.decode(encoding="utf-8", errors="strict")
# 再编码
# print(response_2)
hotels = re.findall('<li id=".*">\s+<a id=".*" href="(.*)">(.*)</a>\s+</li>', response_2)[1:5]
# print(hotels)
# print()
for hotel in hotels:
print(hotel[1], ' ', '预定网站 :', ' ', hotel[0])
# output>
国内酒店 预定网站 : https://hotels.ctrip.com/
海外酒店 预定网站 : https://hotels.ctrip.com/international/?intl=1
民宿客栈 预定网站 : https://inn.ctrip.com/onlineinn/index?channelid=211
海外民宿 预定网站 : https://inn.ctrip.com/onlineinn/international/index?channelid=209
我们在 jupyter notebook 中运行上述的代码后显示如下图:
总之就是说:
只要我们提前查看了编码,那么我们就可以直接写出如何解码、如何编码,从而不必去异常处理了,这里写出来主要是要提醒大家有这么一个问题存在的。
最后感谢你的阅读啦~~
喜欢的话就点个赞嘛~~~