aBl*_*aze 5 python url character-encoding python-3.x
我遇到过其中包含\ u Unicode字符的URL,例如以下内容(请注意,这不会映射到有效页面 - 这只是一个示例).
http://my_site_name.com/\u0442\uab86\u0454\uab8eR-\u0454\u043d-\u043c/23795908
如何使用Python对这样的URL进行解码/编码,以便我可以成功地执行HTTP GET以从此网页检索数据?
从技术上讲,这些不是有效的 URL,但它们是有效的 IRI(国际化资源标识符),如RFC 3987 中所定义。
将 IRI 编码为 URI 的方式是:
例如(取自链接的维基百科文章),这个 IRI:
https://en.wiktionary.org/wiki/?????
Run Code Online (Sandbox Code Playgroud)
… 映射到这个 URI:
https://en.wiktionary.org/wiki/%E1%BF%AC%CF%8C%CE%B4%CE%BF%CF%82
Run Code Online (Sandbox Code Playgroud)
我相信可以requests开箱即用地处理这些(尽管最近才出现,并且只有“部分支持”直到 3.0,我不确定这意味着什么)。我很确定urllib2在 Python2.7 中没有,urllib.request在 Python 3.6 中可能也没有。
无论如何,如果您选择的 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)
Run Code Online (Sandbox Code Playgroud)
还有一些第三方库可以处理 IRI,它们大多是从 Twisted 和 Amara 等其他项目中分离出来的。可能值得在 PyPI 中搜索一个而不是自己构建它。
或者,您可能想要一个像hyperlink这样的更高级别的库来处理 RFC 3987(以及RFC 3986,URI 规范的当前版本requests——2.x 和 Python 3.6 stdlib 都处理得不太正确)中的所有复杂问题。
如果您必须手动处理 IRI,则很有可能您还必须处理 IDN国际化域名来代替 ASCII 域名,即使它们在技术上是不相关的规范。所以你可能想要做这样的事情:
def iri_to_uri(iri):
p = urllib.parse.urlparse(iri)
netloc = p.netloc.encode('idna').decode('ascii')
path = urllib.parse.quote_from_bytes(p.path.encode('utf-8'))
p = [:1] + (netloc, path) + p[3:]
return urllib.parse.urlunparse(p2)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
275 次 |
| 最近记录: |