3.1.2 处理异常
urllib的error模块定义了request模块产生的异常,如果出现了问题,request模块便会抛出error模块中定义的异常。
1. URLError
继承与OSError,由request模块产生的异常都可以通过补货这个类来处理。
它具有一个属性,reason——返回错误的原因
from urllib import request,error
try:
response = request.urlopen("https://cuiqingtai.com/index.htm")
except error.URLError as e:
print(e.reason)
输出:
[Errno 8] nodename nor servname provided, or not known
2.HTTPError
是URLError的子类,专门用来处理HTTP请求错误,例如:认证请求失败。有三个属性:
1、code:返回HTTP状态码,比如404网页不存在,500表示服务器内部错误
2、reason:和父类一样,返回错误的原因
3、headers:返回请求头
实例:
from urllib import request,error
try:
response = request.urlopen("https://cuiqingtai.com/index.htm")
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 Successfully!')
这里是比较好的写法~先捕捉子类的错误,再去捕捉父类的错误。
注意哦:有时候reason返回的不是一个字符串而是一个对象
实例如下~
try:
response = urllib.request.urlopen('https://www.baidu.com',timeout=0.01)
except urllib.error.URLError as e:
print(type(e.reason))
if isinstance(e.reason,socket.timeout):
print('TIME OUT')
输出的是socket.time对象~
我们这里可以用isinstance()来判断reason返回的对象类型,以获得更精准的异常判断。
<class 'socket.timeout'>
TIME OUT
3.1.3 解析链接
1、urlparse(): 该方法可以实现URL的识别和分段
实例如下~
from urllib.parse import urlparse
result = urlparse('http://www.baidu.com/index.html;user?id=5#comment')
print(type(result))
print(result)
这里使用了urlparse()方法做了一个URL解析,输出了解析类型(ParseResult类型的对象),然后将结果输出
输出如下:
<class 'urllib.parse.ParseResult'>
ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=5', fragment='comment')
ParseResult类型的对戏那个包含6个部分:
scheme、netloc、path、params、query、fragement
下面对解析结果分析:
http://www.baidu.com/index.html;user?id=5#comment
1、: / /前面的就是scheme,代表协议
2、第一个/符号前面的就是netloc,域名;后面是path,访问路径
3、分号;后面是params,参数
4、问号?后面是查询条件query,一般用作GET类型的URL
5、#后面的是锚点fragment,用于定位页面内部的下拉位置。
所以可以得出一个标准链接的格式:
scheme://netloc/path;params?query#fragement
urlparse()可以将其拆分开来。
下面来看看urlparse的API用法:
urllib.parse.urlparse(urlstring, scheme='', allow_fragments=True)
__urlstring:__必填项,待解析的URL
__scheme:__默认的协议(比如http或者https)。假如URL没有带有协议信息,那么会将这个当成默认协议。
实例如下~
from urllib.parse import urlparse
result = urlparse("www.baidu.com/index.html;user?id=5#comment",scheme='https')
print(result)
运行结果如下:
ParseResult(scheme='https', netloc='', path='www.baidu.com/index.html', params='user', query='id=5', fragment='comment')
__allow_fragments:__即是否可以忽略fragment。如果被设置成false,那么fragment会被忽略,它会被解析成path、params或者query的一部分,fragment部分为空。
实例如下~
from urllib.parse import urlparse
result = urlparse('http://www.baidu.com/index.html;user?id=5#comment',allow_fragments=False)
print(result)
结果如下:
ParseResult(scheme='http', netloc='www.baidu.com', path='/index.html', params='user', query='id=5#comment', fragment='')
fragment被包含在了query中。
同理,如果URL中如果没有包含query、params,那么fragment和query、params会被包含在path中
这里ParseResult实际上是一个元组,我们可以用下表引用也可以用属性名获取。
eg:
result.scheme = result[0]
2.urlunparse():
它接受的参数是一个可迭代对象,长度必须为6,要不然会报错的。
实例如下:
from urllib.parse import urlunparse
data = ['http','www.baidu.com','index.html','user','a=6','comment']
print(urlunparse(data))
输出一个URL:
http://www.baidu.com/index.html;user?a=6#comment
3.urlsplit():
这个方法与urlparse()方法类似,但是不再单独解析params,只返5个结果。params会合并到path中。
实例如下:
假装有例子
假装有输出
urlsplit()方法返回的结果是SplitResult,是一个元组类型既可以用属性获取值,又可以用索引来获取。与urlparse()一样的。
4.urlunsplit():
与urlsplit()相对应,与urlunparse()类似,也是将链接的各个部分组合成完整链接的方法。传入的参数也是一个可迭代对象,只不过长度是5。
5.urljoin():
除了可以用urlunparse() and urlunsplit()完成链接的合并,还可以使用urljoin()方法~我们可以提供一个base_url来作为第一个参数,然后将一个新链接作为第二个参数。该方法会分析base_url的scheme,netloc,path这3个内容,并且对新链接进行补充,返回最终结果。
具体代码分析如下:
print(urljoin('http://www.baidu.com','FAQ.html'))
print(urljoin('http://www.baidu.com/about.html','https://cuiqingcai.com/FAQ.html'))
输出如下~
http://www.baidu.com/FAQ.html
https://cuiqingcai.com/FAQ.html
注意~
这三个参数只是对新链接缺少的部分进行填充,如果新链接本身就有了,那么就不用对新链接进行替换了。而旧链接的params, query, fragment是不起作用的哦~
6.urlencode():
这个常用的方法在构造GET请求参数的时候很有用。
实例如下~
from urllib.parse import urlencode
params = {
'name' : 'germey',
'age' :22
}
base_url = 'http://www.baidu.com?'
url = base_url + urlencode(params)
print(url)
输出如下~
http://www.baidu.com?name=germey&age=22
这里可以看到哈,参数成功由字典类型经urlencode()转化成GET请求参数了~(该方法很常用哈)
7.parse_qs():
这个是对应于urlencode()的反序列化方法:将GET请求参数转化成字典~
实例如下~
from urllib.parse import parse_qs
query = 'name=germey&age=22'
print(parse_qs(query))
输出如下~
{'name': ['germey'], 'age': ['22']}
8.parse_qsl():
将参数转化为元组组成的列表~
具体例子与上面的parse_qs()相似
9.quote():
该方法可以将内容转化为URL编码的格式~
如果URL带有中文参数,有时候可能导致乱码的问题,所以此时用这个方法可以将中文字符转化为URL编码~
实例如下:
from urllib.parse import quote
keyword = '壁纸'
url = 'https://www.baidu.com/s?wd=' + quote(keyword)
print(url)
输出如下~
https://www.baidu.com/s?wd=%E5%A3%81%E7%BA%B8
PS:我感觉这个很有趣呀,感觉现在可以看懂了很多的URL了,之前以为这些后面乱七八糟的是啥玩意,现在都能用接下来的方法来解码URL了呢~
10.unquote()
这个方法是对URL进行解码的~
实例如下~
from urllib.parse import unquote
url = 'https://www.baidu.com/s?wd=%E5%A3%81%E7%BA%B8'
print(unquote(url))
输出如下:
https://www.baidu.com/s?wd=壁纸
以上就是parse模块的一些常用的URL方法啦,我们可以用这些方法对URL解析和构造哦,最好熟练掌握~