文章目录
- Python爬虫
- 三、解析链接——parse
Python爬虫
三、解析链接——parse
- parse模块定义了处理URL 的标准接口,例如实现URL 各部分的抽取、合并以及链接转换。
- urlparse()
- 该方法可以实现URL 的识别和分段
from urllib.parse import urlparse
result = urlparse('http://www.baidu.com/index.html;user?id=5#comment')
print(type(result),result)
结果如下
可以看到,返回结果是一个ParseResult 类型的对象,它包含6个部分,分别是scheme、netloc、path、params 、query 和fragment 。
- 可以发现,urlparse()方法将其拆分成了6 个部分。大体观察可以发现,解析时有特定的分隔符。比如,😕/前面的就是scheme ,代表协议;第一个/符号前面便是netloc,即域名,后面是path,即访问路径;分号前面是params,代表参数;问号?后面是查询条件query,一般用作GET 类型的URL;井号#后面是锚点fragment,用于直接定位页面内部的下拉位置。
- 一个标准的URL 都会符合这个规则,利用urlparse()方法可以将它拆分开来。
- urlparse()方法的API 用法:
urllib.parse.urlparse(urlstring,scheme=’’,allow_fragments=True)
- urlstring:必填项,即待解析的URL 。
- scheme:它是默认的协议(比如http 或https 等)。假如这个链接没有带协议信息,会将这个作为默认的协议。
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’)
可以发现,我们提供的URL 没有包含最前面的scheme 信息,但是通过指定默认的scheme 参数,返回的结果是https 。
如果URL中本来就带有scheme信息,那就会解析出本来的scheme。即scheme 参数只有在URL中不包含scheme 信息时才生效。
- 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=’’)
当URL 中不包含params 和query 时, fragment 便会被解析为path 的一部分。总之是被合并在了前面的一个部分。
- 返回结果ParseResult 实际上是一个元组,我们可以用索引顺序来获取,也可以用属性名获取。
from urllib.parse import urlparse
result = urlparse('http://www.baidu.com/index.html;user?id=5#comment')
print(result.scheme,result[1],result.neclot)
- urlunparse()
- urlparse()的对立方法urlunparse() 。它接受的参数是一个可迭代对象,但是它的长度必须是6,否则会抛出参数数量不足或者过多的问题。
from urllib.parse import urlunparse
data =['http','www.baidu.com','index.html','user','a=6','comment']
print(urlunparse(data))
data也可以使用元组等类型
- urlsplit()
- 和urlparse()方法非常相似, 只不过它不再单独解析pa rams 这一部分,只返回5个结果。上面例子中的params 会合并到path 中。
from urllib.parse import urlsplit
result = urlsplit('http://www.baidu.com/index.html;user?id=5#comment')
print(result)
结果:
SplitResult(scheme=‘http’, netloc=‘www.baidu.com’, path=’/index.html;user’, query=‘id=5’, fragment=‘comment’)
返回结果是SplitResult,它其实也是一个元组类型, 既可以用属性获取值,也可以用索引来获取。
from urllib.parse import urlsplit
result = urlsplit('http://www.baidu.com/index.html;user?id=5#comment')
print(result.scheme,result[0])
- urlunsplit()
- 与urlunparse()类似,它也是将链接各个部分组合成完整链接的方法,传人的参数也是一个可迭代对象,例如列表、元组等,唯一的区别是长度必须为5 。
from urllib.parse import urlunsplit
data =['http', 'www.baidu.com','index.html','a=6','comment']
print(urlunsplit(data))
- urljoin()
- 生成链接还有另一个方法,那就是urljoin()方法。我们可以提供一个base_url(基础链接) 作为第一个参数,将新的链接作为第二个参数,该方法会分析base_url的scheme、netloc 和path这3个内容并对新链接缺失的部分进行补充,最后返回结果。
from urllib.parse import urljoin
print(urljoin('http://www.baidu.com','FAQ.html'))
print(urljoin('http://www.baidu.com','https://cuiqingcai.com/FAQ.html'))
print(urljoin('http://www.baidu.com/about.html','https://cuiqingcai.com/FAQ.html'))
print(urljoin('http://.baidu.com/about.html','https://cuiqingcai.com/FAQ.html?question=2'))
print(urljoin('http://www.baidu.com','?category=2#comment'))
print(urljoin('www.baidu.com','?category=2#comment'))
结果:
http://www.baidu.com/FAQ.html https://cuiqingcai.com/FAQ.html
https://cuiqingcai.com/FAQ.html
https://cuiqingcai.com/FAQ.html?question=2
http://www.baidu.com?category=2#comment
www.baidu.com?category=2#comment
- 可以发现, base_url 提供了三项内容scheme、netloc 和path 。如果这3 项在新的链接里不存在,就予以补充;如果新的链接存在,就使用新的链接的部分。而base_url中的params、query、fragment是不起作用的。
- urlencode()
- 它在构造GET 请求参数的时候非常有用
from urllib.parse import urlencode
data = {
'name':'Jerry',
'age':'20'
}
base_url = 'http://www.baidu.com?'
url = base_url+urlencde(data)
print(url)
结果:
http://www.baidu.com?name=Jerry&age=20
调用urlencode()方法可以将包含参数的字典序列化为GET 请求参数。有时为了更加方便地构造参数,我们会事先用字典来表示。要转化为URL的参数时,只需要调用该方法即可。
- parse_qs()
- 可以反序列化。如果我们有一串GET 请求参数,利用parse_qs()方法, 就可以将它转回字典。
from urllib.parse import parse_qs
query = 'name=Jerry&age=20'
print(parse_qs(query))
结果:
{‘name’: [‘Jerry’], ‘age’: [‘20’]}
- parse_qsl()
- parse_qsl()方法,用于将参数转化为元组组成的列表
from urllib.parse import parse_qsl
query = 'name=Jerry&age=20'
print(parse_qsl(query))
结果:
[(‘name’, ‘Jerry’), (‘age’, ‘20’)]
运行结果是一个列表,而列表中的每一个元素都是一个元组,元组的第一个内容是参数名,第二个内容是参数值。
- quote()
- 该方法可以将内容转化为URL 编码的格式。URL中带有中文参数时,有时可能会导致乱码的问题,此时用这个方法可以将中文字符转化为URL 编码。
from urllib.parse import quote
keyword = '海贼王'
url = 'http://www.baidu.com/s?wd='+quote(keyword)
print(url)
结果:
http://www.baidu.com/s?wd=%E6%B5%B7%E8%B4%BC%E7%8E%8B
- unquote()
- 与quote()相反,unquote()可以进行URL 解码。
from urllib.parse import unquote
url = 'http://www.baidu.com/s?wd=%E6%B5%B7%E8%B4%BC%E7%8E%8B'
print(unquote(url))
结果:
http://www.baidu.com/s?wd=海贼王
- 有了以上介绍的parse中的这些方法,我们可以方便地实现URL 的解析和构造,建议熟练掌握。