urllib最常用的模块

 经常在一些第三方模块中还会再见到urllib2,python3版本已经将urllib2干掉,将和原有的urllib合为一体。其官方文档链接为:https://docs.python.org/3/library/urllib.html urllib提供了四个重要的模块,他们分别是request、parse、error和robotparser。在日常开发中,只有parse模块有用到,而其他的三个模块,我们常常将会使用第三方模块requests来替代,requests功能强大,使用更便捷,是目前使用http请求库中最好用的,没有之一。下面我们简单介绍parse模块的使用。

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参数处理

1. url解析

url解析我归类为urlparse、urlunparse、urlsplit、urlunsplit 和 urljoin

urlparse

    解析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函数,下面再介绍它。  

urlunparse

    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

urlsplit

    前面提到的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')

urlunsplit

    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

urljoin

    前面的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

2. url参数处理

url参数处理,我整理为:urlencode、parse_qs、parse_qsl、quote 和 unquote

urlencode

  将字典序列化为 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

parse_qs

  参数反序列化,分解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&amp;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_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&amp;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', '')]

quote

   将内容转化为 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

  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= 爬虫 

猜你喜欢

转载自www.cnblogs.com/lynn578/p/12181734.html