Python 要如何处理直接从直接 bytes 进行百分号编码的 url query?

2023-07-14 20:28:08 +08:00
 Trim21

我现在有一些 url 的 query 是直接从 bytes 进行百分号编码之后拼接成的。

但是 python 的 urllib.parse.parse_qs 的解析是基于 str 的,默认所有的 query 都是百分比编码的字符串,在解析的时候会先解析为 bytes ,然后 bytes.decode(encoding=encoding) 转成字符串。

所以用 parse_qs 无法解析这些 query string 。

标准库里同时提供了 unquote_to_bytes,但是并没有对应的 parse_qs_to_bytes 来解析整个 query string ,有什么简单地办法来处理这个 query ?

如果要自己手动分割 query string 的话感觉相当于要重新实现 parse_qs

from urllib.parse import parse_qs, quote, unquote_to_bytes, urlparse


raw_bytes = bytes.fromhex('123456789abcdef123456789abcdef123456789a')

url = f'https://example.com/?q={quote(raw_bytes)}'
print(url)

assert unquote_to_bytes(quote(raw_bytes)) == raw_bytes

parsed_q = parse_qs(urlparse(url).query).get("q")[0].encode()
print(parsed_q.hex())  # 12345678efbfbdefbfbdefbfbdefbfbd234567efbfbdefbfbdefbfbdefbfbd12345678efbfbd

https://gist.github.com/trim21/b60d3999bea03bcac403380d4b157a02

1324 次点击
所在节点    Python
8 条回复
NoOneNoBody
2023-07-14 21:57:29 +08:00
需要自己写个闭包,因为编码是不确定的
wali77
2023-07-14 22:04:26 +08:00
mrzhu
2023-07-14 22:20:09 +08:00
没想到在这里碰到你 bgm
Trim21
2023-07-14 22:21:11 +08:00
@NoOneNoBody 为什么要闭包…

研究了一下,解决方法应该是 encoding=raw_unicode_escape 编码解析 querystring ,然后再用这个编码把字符串的 encode/decode 为 bytes ,就是正确的结果了。如果有其他的 UTF8 query 的话再手动用对应编码转换一下。
mrzhu
2023-07-14 22:21:25 +08:00
😂
NoOneNoBody
2023-07-14 22:39:08 +08:00
@Trim21 #4
单纯解决问题当然不需要

写成 fun 就是为了复用,方便调用,各种 iterable 使用 map/apply ,传参 encoding 就够了
web 的东西,除非是某个网站独有的处理过程,不然复用可能性很高
lanlanye
2023-07-15 01:18:44 +08:00
参数是全都用这种形式传递吗?还是说混合了多种不同的编码方式?

前者的话自己写个工具函数切一下也不是很费劲,后者最好考虑一下换种传参方式?
Trim21
2023-07-15 01:40:51 +08:00
@lanlanye #7 只有没编码的 bytes 和 ascii 编码两种情况。

呃,这么一说我才发现其实就是 `latin-1` 编码?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/956863

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX