如何在Flask中获取HTTP GET请求的二进制格式参数?(BitTorrent追踪器)
解决BitTorrent追踪器中提取二进制info_hash的问题
好问题!我之前开发BT追踪器的时候也踩过这个坑——Flask的request.args默认会把GET参数解码成字符串,但info_hash是纯二进制序列,根本没法用常规编码转成可读字符串,确实头疼。不过不用自己写解析器,Flask本身就有现成的解决方案:
方法一:使用request.args.get_raw()(推荐)
Werkzeug(Flask底层的WSGI工具库)提供了get_raw()方法,它会直接返回原始的字节串,完全跳过自动解码步骤,完美匹配BT协议的需求。
示例代码:
from flask import Flask, request app = Flask(__name__) @app.route('/announce') def handle_announce(): # 直接获取字节形式的info_hash info_hash = request.args.get_raw('info_hash') # 验证一下:BT的info_hash固定是20字节 if len(info_hash) != 20: return "Invalid info_hash", 400 # 接下来就可以用这个字节串和种子的info_hash做对比等操作了 print(f"Received info_hash (bytes): {info_hash}") return "Announce processed" if __name__ == '__main__': app.run(port=5000)
这个方法是最简洁也最符合设计意图的,只要你的Flask版本对应的Werkzeug在0.15以上(现在主流版本都满足),直接用就行。
方法二:从原始URL解析(备选方案)
如果因为特殊原因没法用get_raw(),也可以手动解析请求的原始URL,用urllib.parse提取未解码的参数:
from flask import Flask, request from urllib.parse import urlparse, parse_qs app = Flask(__name__) @app.route('/announce') def handle_announce(): parsed_url = urlparse(request.url) # 关键是设置keep_blank_values=True,并且不自动解码 query_params = parse_qs(parsed_url.query, keep_blank_values=True, encoding=None) info_hash = query_params.get('info_hash', [b''])[0] print(f"Received info_hash (bytes): {info_hash}") return "Announce processed"
不过这个方法需要自己处理参数的列表结构,不如第一种方法优雅,优先推荐用get_raw()。
注意事项
- BT协议规定info_hash是20字节的二进制数据,拿到字节串后可以直接和从种子文件中解析出的info_hash做字节级对比,不需要再做任何编码转换。
- 如果遇到编码相关的报错,检查一下Flask的配置,确保没有强制设置全局的请求编码,保持默认的二进制处理逻辑即可。
内容的提问来源于stack exchange,提问作者user2993837




