标题:Python之异常处理方法
文章目录
- 标题:Python之异常处理方法
 
- 一、什么是异常?
 - 二、常用的python标准异常
 - 三、另附HTTP状态码
 - 四、异常处理语法
 
- 1、方法1
 - 2、方法2
 - 3、方法3
 
- 五、异常处理举例
 
- 举例1:ZeroDivisionError
 - 举例2:AttributeError
 - 举例3:UnicodeError
 
- 1、字符编码相关知识
 - 2、爬虫实例
 
一、什么是异常?
首先,异常是一个事件,该事件会在程序执行过程中发生,并且会影响程序的正常运行。一般情况下,在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
运行结果的图片展示:
 (这里还是使用了 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 中运行上述的代码后显示如下图:

 总之就是说:
只要我们提前查看了编码,那么我们就可以直接写出如何解码、如何编码,从而不必去异常处理了,这里写出来主要是要提醒大家有这么一个问题存在的。
最后感谢你的阅读啦~~
喜欢的话就点个赞嘛~~~
                










