经常在一些第三方模块中还会再见到urllib2,python3版本已经将urllib2干掉,将和原有的urllib合为一体。
urllib提供了四个重要的模块,他们分别是request、parse、error和robotparser。在日常开发中,只有parse模块有用到,而其他的三个模块,我们常常将会使用第三方模块requests来替代,requests功能强大,使用更便捷,是目前使用http请求库中最好用的,没有之一。下面我们简单介绍parse模块的使用。parse 模块定义了处理 URL 的标准接口,例如实现 URL 各部分的抽取、合并以及链接转换。它支持如下协议的 URL 处理:
file、ftp、gopher、hdl、http、https、imap、mailto、 mms、news、nntp、prospero、rsync、rtsp、rtspu、sftp、 sip、sips、snews、svn、svn+ssh、telnet 和 wais。
这里我将parse以功能区分为:url解析和url参数处理
url解析我归类为urlparse、urlunparse、urlsplit、urlunsplit 和 urljoin
解析url,将其拆解划分。
函数:urllib.parse.urlparse(urlstring, scheme=‘‘, allow_fragments=True)
urlstring:url字符串
scheme:url协议,当url自身存在协议时(不管合不合法),该参数失效
allow_fragments:是否忽略 fragment(描点)参数
from urllib.parse import urlparse result = urlparse(‘http://www.baidu.com/index.html;user?id=5#comment‘) print(type(result), result) # <class ‘urllib.parse.ParseResult‘> # ParseResult( # scheme=‘http‘, # 协议 # netloc=‘www.baidu.com‘, # 域名 # path=‘/index.html‘, # 路径 # params=‘user‘, # 参数 # query=‘id=5‘, # 查询条件 # fragment=‘comment‘ # #后面是锚点,用于直接定位页面内部的下拉位置 # )
解析完url之后我们拿到的是一个元组类型的urllib.parse.ParseResult对象,我们可以通过对象的特性来获取解析后的值,也可以通过元组的索引来取值。在解析出来的参数中,更多的情况下,我们往往是将path和params参数和在一起,这时候可以使用urllib.parse.urlsplit函数,下面再介绍它。
url构造器,开发中比较少用
函数:urllib.parse.urlunparse(components)
components:一个可迭代序列,个数必须是6,否则抛出参数不足异常
from urllib.parse import urlunparse data = [‘http‘, ‘www.baidu.com‘, ‘index.html‘, ‘user‘, ‘a=6‘, ‘comment‘] print(urlunparse(data)) # http://www.baidu.com/index.html;user?a=6#comment
前面提到的urlparse解析完是将参数path和params分开的,这里的urlsplit是将其合为一体,
函数:urllib.parse.urlsplit(urlstring, scheme=‘‘, allow_fragments=True)
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‘)
url组合,和urlunparse的区别是,它只需要5个参数
函数:urllib.parse.urlunsplit(components)
from urllib.parse import urlunsplit data = [‘http‘, ‘www.baidu.com‘, ‘index.html‘, ‘a=6‘, ‘comment‘] print(urlunsplit(data)) # http://www.baidu.com/index.html?a=6#comment
前面的url组合器一般我本人很少用到,一般用的多是这个urljon,它不需要有特定长度的对象
函数:urllib.parse.urljoin(base, url, allow_fragments=True)
base:基础链接
url:新的链接,根据base参数的 scheme、netloc 和 path 这 3 个内容对url缺失的部分进行补充
from urllib.parse import urljoin print(urljoin(‘http://www.baidu.com/about.html‘, ‘https://www.cnblogs.com/lynn578/p/11870205.html‘)) # https://www.cnblogs.com/lynn578/p/11870205.html print(urljoin(‘http://www.baidu.com?wd=abc‘, ‘cnblogs.com/lynn578/p/11870205.html‘)) # http://www.baidu.com/cnblogs.com/lynn578/p/11870205.html print(urljoin(‘http://www.baidu.com‘, ‘?category=2#comment‘)) # http://www.baidu.com?category=2#comment print(urljoin(‘www.baidu.com‘, ‘?category=2#comment‘)) # www.baidu.com?category=2#comment print(urljoin(‘www.baidu.com#comment‘, ‘?category=2‘)) # www.baidu.com?category=2
url参数处理,我整理为:urlencode、parse_qs、parse_qsl、quote 和 unquote
将字典序列化为 GET 请求参数
函数:urllib.parse.urlencode(query, doseq=False, safe=‘‘, encoding=None, errors=None, quote_via=quote_plus)
query:序列类型。一般为dict类型,也可以为二元组类型
doseq:若query中的key-value的value为序列类型,且doseq为False(默认)时,将其转义;否则将其值的每个元素和原有的key进行组合(注意:如果每个元素的值再次为序列类型,再次转义改值)
quote_via:默认值为quote_plus(一个函数地址)。表示遵循GET请求(application/x-www-form-urlencoded)的标准。将空格转义为“+”字符,将“/”转义为“%2F”字符。
其他safe、encoding 和 errors 等参数将会被传递给quote_via
from urllib.parse import urlencode params = {‘code‘: 12, ‘redirect‘: "https://www.baidu.com?redirect=https://wwww.douban.com"} base_url = ‘https://dig.chouti.com?‘ url = base_url + urlencode(params) # https://dig.chouti.com?code=12&redirect=https%3A%2F%2Fwww.baidu.com%3Fredirect%3Dhttps%3A%2F%2Fwwww.douban.com params = ((‘code‘, 123123), (‘redirect‘, [‘p1‘, ‘p2‘])) base_url = ‘https://open.weixin.qq.com/connect/oauth2/authorize?‘ url = base_url + urlencode(params) # https://open.weixin.qq.com/connect/oauth2/authorize?code=123123&redirect=%5B%27p1%27%2C+%27p2%27%5D params = {‘code‘: 12, ‘redirect‘: [‘p1‘, ‘p2‘]} base_url = ‘https://open.weixin.qq.com/connect/oauth2/authorize?‘ url_1 = base_url + urlencode(params) # https://open.weixin.qq.com/connect/oauth2/authorize?code=12&redirect=%5B%27p1%27%2C+%27p2%27%5D # [‘p1‘, ‘p2‘]被转义为%5B%27p1%27%2C+%27p2%27%5D url_2 = base_url + urlencode(params, doseq=True) # https://open.weixin.qq.com/connect/oauth2/authorize?code=12&redirect=p1&redirect=p2 params = {‘code‘: 12, ‘redirect‘: ((‘p1‘, ‘p2‘), (‘p1‘, ‘p2‘))} base_url = ‘https://open.weixin.qq.com/connect/oauth2/authorize?‘ url_2 = base_url + urlencode(params, doseq=True) # https://open.weixin.qq.com/connect/oauth2/authorize?code=12&redirect=%28%27p1%27%2C+%27p2%27%29&redirect=%28%27p1%27%2C+%27p2%27%29
参数反序列化,分解GET参数
函数:urllib.parse.parse_qs(qs, keep_blank_values=False, strict_parsing=False, encoding=‘utf-8‘, errors=‘replace‘)
keep_blank_values:当value为空时,表示是否需要显示key,默认为False
strict_parsing:指示如何处理解析错误的标志。如果为false(默认值),则会自动忽略错误。否则错误会引发ValueError异常。
from urllib.parse import parse_qs query1 = ‘name=lynn&age=18&sex=1‘ query2 = ‘name=lynn&name=Jokon&age=18&sex=‘ print(parse_qs(query1)) # {‘name‘: [‘lynn‘], ‘age‘: [‘18‘], ‘sex‘: [‘1‘]} print(parse_qs(query2, keep_blank_values=True)) # {‘name‘: [‘lynn‘, ‘Jokon‘], ‘age‘: [‘18‘], ‘sex‘: [‘‘]}
parse_qsl 和 parse_qs 的区别在于解析后的返回结果不同,parse_qsl返回的元组类型
函数:urllib.parse.parse_qsl(qs, keep_blank_values=False, strict_parsing=False, encoding=‘utf-8‘, errors=‘replace‘)
from urllib.parse import parse_qsl query1 = ‘name=lynn&age=18&sex=1‘ query2 = ‘name=lynn&name=Jokon&age=18&sex=‘ print(parse_qsl(query1)) # [(‘name‘, ‘lynn‘), (‘age‘, ‘18‘), (‘sex‘, ‘1‘)] print(parse_qsl(query2, keep_blank_values=True)) # [(‘name‘, ‘lynn‘), (‘name‘, ‘Jokon‘), (‘age‘, ‘18‘), (‘sex‘, ‘‘)]
将内容转化为 URL 编码的格式。特别是内容存在中文字符时,这种情况是用在网站的搜索系统,下面介绍quote 和 unlencode的区别
函数:urllib.parse.quote(string, safe=‘/‘, encoding=None, errors=None)
string:需要被编码的内容
safe:默认“/”不转义,一般在开发中需要转义,只需要让safe=‘‘即可
from urllib.parse import quote, urlencode keyword = ‘ 爬虫 ‘ url1 = ‘https://www.baidu.com/s?wd=‘ + quote(keyword, safe=‘‘) url2 = ‘https://www.baidu.com/s?‘ + urlencode({‘wd‘: keyword}, quote_via=quote) # https://www.baidu.com/s?wd=%20%E7%88%AC%E8%99%AB%20 # 这两中做法是等价的
unquote是对quote的解码
函数:urllib.parse.unquote(string, encoding=‘utf-8‘, errors=‘replace‘)
from urllib.parse import unquote url = ‘https://www.baidu.com/s?wd=%20%E7%88%AC%E8%99%AB%20‘ print(unquote(url)) # https://www.baidu.com/s?wd= 爬虫
原文:https://www.cnblogs.com/lynn578/p/12181734.html