Python 如何获取http";获得;烧瓶中二进制格式的参数?
我正在尝试写一个bittorrent跟踪器。跟踪器协议将二进制十六进制编码到http“GET”参数中。它看起来类似于以下内容:Python 如何获取http";获得;烧瓶中二进制格式的参数?,python,http,flask,bittorrent,Python,Http,Flask,Bittorrent,我正在尝试写一个bittorrent跟踪器。跟踪器协议将二进制十六进制编码到http“GET”参数中。它看起来类似于以下内容: http://localhost:5000/announce?info_hash=%C5O%94%1b%1a9%86%86%12B%D7U%D0%ACF%E9%FA%3c%5d2 如果我使用request.args,它将尝试将“info_hash”解码为字符串,这将不起作用,因为info_hash应该是一些原始二进制序列,不能用任何字符串编码表示 那么,我是否可以使用
http://localhost:5000/announce?info_hash=%C5O%94%1b%1a9%86%86%12B%D7U%D0%ACF%E9%FA%3c%5d2
如果我使用request.args,它将尝试将“info_hash”解码为字符串,这将不起作用,因为info_hash应该是一些原始二进制序列,不能用任何字符串编码表示
那么,我是否可以使用任何东西来提取以字节为单位的结果,而不必滚动我自己的解析器
谢谢不幸的是,在标准库中似乎没有一种真正简单的方法来实现这一点 方法是通过
request.query\u string
获取原始查询字符串并对其进行解析。问题是Python标准库函数都假定值也是Unicode,这对于Bittorrent跟踪器来说当然不是真的,正如您所指出的
问题是,标准库具有所有必需的功能,即parse_qs
fromurllib.parse
函数,只需稍加修改即可实现:
def parse_qs_to_bytes(qs, keep_blank_values=False, strict_parsing=False,
max_num_fields=None):
parsed_result = {}
pairs = parse_qsl(qs, keep_blank_values, strict_parsing,
max_num_fields=max_num_fields)
for name, value in pairs:
if name in parsed_result:
parsed_result[name].append(value)
else:
parsed_result[name] = [value]
return parsed_result
def parse_qsl(qs, keep_blank_values=False, strict_parsing=False,
max_num_fields=None):
if max_num_fields is not None:
num_fields = 1 + qs.count('&') + qs.count(';')
if max_num_fields < num_fields:
raise ValueError('Max number of fields exceeded')
pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
r = []
for name_value in pairs:
if not name_value and not strict_parsing:
continue
nv = name_value.split('=', 1)
if len(nv) != 2:
if strict_parsing:
raise ValueError("bad query field: %r" % (name_value,))
# Handle case of a control-name with no equal sign
if keep_blank_values:
nv.append('')
else:
continue
if len(nv[1]) or keep_blank_values:
name = nv[0].replace('+', ' ')
name = unquote(name)
value = nv[1].replace('+', ' ')
value = unquote_to_bytes(value) # changed line from original to prevent coercing into unicode
r.append((name, value))
return r
def parse_qs_to_bytes(qs,keep_blank_value=False,strict_parsing=False,
最大数量字段=无):
已解析的_结果={}
pairs=parse_qsl(qs,keep_blank_值,strict_解析,
最大数量字段=最大数量字段)
对于名称,成对的值:
如果解析结果中的名称:
已分析的_结果[名称]。追加(值)
其他:
解析的_结果[名称]=[值]
返回解析的结果
def parse_qsl(qs,keep_blank_values=False,strict_parse=False,
最大数量字段=无):
如果max_num_字段不是None:
num_fields=1+qs.count('&')+qs.count(';'))
如果最大数量字段<数量字段:
raise VALUERROR('超出最大字段数')
pairs=[s1在qs.split('&')中用于s1.split(';')中的s2]
r=[]
对于成对的name_值:
如果不命名\u值且不严格\u解析:
持续
nv=name_value.split('=',1)
如果len(nv)!=2:
如果是严格的语法分析:
raise VALUERROR(“错误的查询字段:%r”%(名称\u值,))
#处理不带等号的控件名称的大小写
如果将_保留为空_值:
内文附加(“”)
其他:
持续
如果len(nv[1])或保留空白值:
名称=nv[0]。替换('+','')
name=unquote(name)
值=nv[1]。替换('+','')
value=unquote_to_bytes(value)#更改了原始行以防止强制转换为unicode
r、 追加((名称、值))
返回r
因此,您应该能够调用parse\u qs\u bytes\u to\u bytes(request.query\u string.decode())