Python3 网络爬虫开发实战 读书笔记(三)

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解析和构造哦,最好熟练掌握~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

艾尔伯特想变瘦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值