Python之异常处理方法

标题: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 中运行上述的代码后显示如下图:
在这里插入图片描述
总之就是说:

只要我们提前查看了编码,那么我们就可以直接写出如何解码、如何编码,从而不必去异常处理了,这里写出来主要是要提醒大家有这么一个问题存在的。

最后感谢你的阅读啦~~

喜欢的话就点个赞嘛~~~

猜你喜欢

转载自blog.csdn.net/m0_54218263/article/details/114821208