我遇到过其中包含\ u Unicode字符的网址,例如以下内容(请注意,这不会映射到有效网页 - 这只是一个示例)。
http://my_site_name.com/\u0442\uab86\u0454\uab8eR-\u0454\u043d-\u043c/23795908
如何使用Python对此类URL进行解码/编码,以便我可以成功执行HTTP GET以从此网页检索数据?
答案 0 :(得分:4)
从技术上讲,这些网址不是有效网址,但它们是有效的IRI(Internationalized Resource Identifiers),如RFC 3987中所定义。
将IRI编码为URI的方式是:
例如(摘自链接的维基百科文章),此IRI:
https://en.wiktionary.org/wiki/Ῥόδος
...映射到此URI:
https://en.wiktionary.org/wiki/%E1%BF%AC%CF%8C%CE%B4%CE%BF%CF%82
我相信requests
处理这些开箱即用(虽然只是最近,而且只有"部分支持"直到3.0,我不确定这意味着什么) 。我非常确定Python2.7中的urllib2
没有,而Python 3.6中的urllib.request
也可能没有。
无论如何,如果您选择的HTTP库不处理IRI,您可以手动执行:
def iri_to_uri(iri):
p = urllib.parse.urlparse(iri)
path = urllib.parse.quote_from_bytes(p.path.encode('utf-8'))
p = [:2] + (path,) + p[3:]
return urllib.parse.urlunparse(p2)
还有许多第三方库来处理IRI,其中大多数是从Twisted和Amara等其他项目中分离出来的。可能值得搜索PyPI而不是自己构建它。
或者您可能需要像hyperlink
这样的更高级别的库来处理RFC 3987中的所有复杂问题(和RFC 3986,URI的规范的当前版本 - 这两者都不是{{1} 2.x也不是Python 3.6 stdlib处理得非常正确。)
如果您必须手动处理IRI,那么您很可能也需要处理IDN Internationalized Domain Names来代替ASCII域名,即使技术上它们是不相关的规范。所以你可能想做这样的事情:
requests
答案 1 :(得分:1)
这是一种在IRI的路径和域部分自动检测和非编码非ASCII的方法:
from urllib.request import quote
def iri_to_uri(iri):
return ("".join([x if ord(x) < 128 else quote(x) for x in iri]))