当前位置: 首页 » 综合知识 » it知识 » 正文

Python如何利用urlliib.parse库解析URL

发布时间:2023-07-20 以下文章来源于网友投稿,内容仅供参考!

解析url

urlparse() 函数可以将 URL 解析成 ParseResult 对象。对象中包含了六个元素,分别为:

from urllib.parse import urlparse url='user:pwd@domain:80/path;params?query=queryarg#fragment' parsed_result=urlparse(url) print('parsed_result 包含了',len(parsed_result),'个元素')print(parsed_result)

结果为:

parsed_result 包含了 6 个元素ParseResult(scheme='http', netloc='user:pwd@domain:80', path='/path', params='params', query='query=queryarg', fragment='fragment')

ParseResult 继承于 namedtuple,因此可以同时通过索引和命名属性来获取 URL 中各部分的值。

为了方便起见, ParseResult 还提供了 username、 password、 hostname、 port 对 netloc 进一步进行拆分。

print('scheme  :', parsed_result.scheme)print('netloc  :', parsed_result.netloc)print('path    :', parsed_result.path)print('params  :', parsed_result.params)print('query   :', parsed_result.query)print('fragment:', parsed_result.fragment)print('username:', parsed_result.username)print('password:', parsed_result.password)print('hostname:', parsed_result.hostname)print('port    :', parsed_result.port)

结果为:

scheme  : httpnetloc  : user:pwd@domain:80path    : /pathparams  : paramsquery   : query=queryargfragment: fragmentusername: userpassword: pwdhostname: domainport    : 80

除了 urlparse() 之外,还有一个类似的 urlsplit() 函数也能对 URL 进行拆分,所不同的是, urlsplit() 并不会把 路径参数(params) 从 路径(path) 中分离出来。

当 URL 中路径部分包含多个参数时,使用 urlparse() 解析是有问题的:

url='user:pwd@domain:80/path2;params1/path3;params2?query=queryarg#fragment' parsed_result=urlparse(url) print(parsed_result)print('parsed.path    :', parsed_result.path)print('parsed.params  :', parsed_result.params)

结果为:

ParseResult(scheme='http', netloc='user:pwd@domain:80', path='/path2;params1/path3', params='params2', query='query=queryarg', fragment='fragment')parsed.path    : /path2;params1/path3parsed.params  : params2

这时可以使用 urlsplit() 来解析:

from urllib.parse import urlsplitsplit_result=urlsplit(url) print(split_result)print('split.path    :', split_result.path)# SplitResult 没有 params 属性

结果为:

SplitResult(scheme='http', netloc='user:pwd@domain:80', path='/path2;params1/path3;params2', query='query=queryarg', fragment='fragment')split.path    : /path2;params1/path3;params2

若只是要将 URL 后的 fragment 标识拆分出来,可以使用 urldefrag() 函数:

from urllib.parse import urldefrag url = 'user:pwd@domain:80/path2;params1/path3;params2?query=queryarg#fragment' d = urldefrag(url)print(d)print('url     :', d.url)print('fragment:', d.fragment)

结果为:

DefragResult(url='user:pwd@domain:80/path2;params1/path3;params2?query=queryarg', fragment='fragment')url     : user:pwd@domain:80/path2;params1/path3;params2?query=queryargfragment: fragment

组建URL

ParsedResult 对象和 SplitResult 对象都有一个 geturl() 方法,可以返回一个完整的 URL 字符串。

print(parsed_result.geturl())print(split_result.geturl())

结果为:

user:pwd@domain:80/path2;params1/path3;params2?query=queryarg#fragmentuser:pwd@domain:80/path2;params1/path3;params2?query=queryarg#fragment

但是 geturl() 只在 ParsedResult 和 SplitResult 对象中有,若想将一个普通的元组组成 URL,则需要使用 urlunparse() 函数:

from urllib.parse import urlunparseurlpos = ('http', 'user:pwd@domain:80', '/path2;params1/path3', 'params2', 'query=queryarg', 'fragment')print(urlunparse(urlpos))

结果为:

user:pwd@domain:80/path2;params1/path3;params2?query=queryarg#fragment

相对路径转换绝对路径

除此之外,urllib.parse 还提供了一个 urljoin() 函数,来将相对路径转换成绝对路径的 URL。

from urllib.parse import urljoin print(urljoin('www.example/path/file.html', 'anotherfile.html'))print(urljoin('www.example/path/', 'anotherfile.html'))print(urljoin('www.example/path/file.html', '../anotherfile.html'))print(urljoin('www.example/path/file.html', '/anotherfile.html'))

结果为:

www.example/path/anotherfile.htmlwww.example/path/anotherfile.htmlwww.example/anotherfile.htmlwww.example/anotherfile.html

查询参数的构造和解析

使用 urlencode() 函数可以将一个 dict 转换成合法的查询参数:

from urllib.parse import urlencode query_args = {    'name': 'dark sun',    'country': '中国'} query_args = urlencode(query_args)print(query_args)

结果为:

name=dark+sun&country=%E4%B8%AD%E5%9B%BD

可以看到特殊字符也被正确地转义了。

相对的,可以使用 parse_qs() 来将查询参数解析成 dict。

from urllib.parse import parse_qsprint(parse_qs(query_args))

结果为:

{'name': ['dark sun'], 'country': ['中国']}

如果只是希望对特殊字符进行转义,那么可以使用 quote 或 quote_plus 函数,其中 quote_plus 比 quote 更激进一些,会把 :/ 一类的符号也给转义了。

from urllib.parse import quote, quote_plus, urlencode url = 'localhost:1080/~hello!/'print('urlencode :', urlencode({'url': url}))print('quote     :', quote(url))print('quote_plus:', quote_plus(url))

结果为:

urlencode : url=http%3A%2F%2Flocalhost%3A1080%2F%7Ehello%21%2Fquote     : http%3A//localhost%3A1080/%7Ehello%21/quote_plus: http%3A%2F%2Flocalhost%3A1080%2F%7Ehello%21%2F

可以看到 urlencode 中应该是调用 quote_plus 来进行转义的。

逆向操作则使用 unquote 或 unquote_plus 函数:

from urllib.parse import unquote, unquote_plus encoded_url = 'http%3A%2F%2Flocalhost%3A1080%2F%7Ehello%21%2F'print(unquote(encoded_url))print(unquote_plus(encoded_url))

结果为:

localhost:1080/~hello!/localhost:1080/~hello!/

你会发现 unquote 函数居然能正确地将 quote_plus 的结果转换回来。

  • • Linux Ecdsa密钥长度选择有何依据

    在Linux

  • • Linux Khook在内核监控中的应用如何

    Linux

  • • Linux Gsoap是否支持异步通信

    GSOAP是

  • • Linux Coremail如何提升用户体验

    提升Linu

  • • Linux Ecdsa算法有哪些局限性

    ECDSA

  • 哎呀音乐钢琴键盘学习《 钢琴主人训练营》 西瓜学琴
    郭蝈 陪练钢琴 30节课时 考级刚需 让孩子每一次练琴都是高质量的
    30天轻松学会五线谱 流行钢琴自学初级教程 牙牙学琴
    流行爵士钢琴实战技巧VIP课 - 继伟 哎呀音乐
    【海上钢琴师】原版 MT1990钢琴谱
    百首经典流行钢琴实战曲集 - 继伟
    雷费尔德电钢琴重锤88键专业考级儿童初学者数码电子钢琴家用
    小练咖 真人钢琴陪练 1v1服务 2999随时退 1课时50分钟 考级刚需
    雅马哈电钢琴88键重锤CLP735智能数码电子钢琴家用专业初学者考级
    【原装进口】Yamaha/雅马哈钢琴 b121 SC2原声静音钢琴
  • 珠海专业调钢琴
  • 天津宝坻区调钢琴
  • 天津静海区钢琴调音
  • 成都简阳市钢琴调律
  • 大连瓦房店市钢琴调音
  • 眉山调钢琴联系方式
  • 惠州大亚湾钢琴调琴师
  • 长治调琴师
  • 厦门湖里区钢琴调音师
  • 上海普陀区钢琴调音师