我有一个用Flask-RESTful开发的webhook,它通过POST获取多个参数。参数之一是用cp1251编码的非Unicode字符串。
找不到使用reqparse
正确解析此参数的方法。
这是我的代码片段:
parser = reqparse.RequestParser()
parser.add_argument('text')
msg = parser.parse_args()
然后,我将msg
写入文本文件,看起来像这样:
{"text": "\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd !\n\n\ufffd\ufffd\ufffd\ufffd\ufffd\n\n-- \n\ufffd \ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd."}
如您所见,Flask以某种方式用\ufffd
替换了所有西里尔字母。同时,正确处理了非西里尔字母,例如!
或\n
。
我可以采取什么措施来建议RequestParser使用字符串编码?
这是我的代码,用于将文本写入磁盘:
f = open('log_msg.txt', 'w+')
f.write(json.dumps(msg))
f.close()
我尝试了f = open('log_msg.txt', 'w+', encoding='cp1251')
,结果相同。
然后,我尝试了
f = open('log_msg_ascii.txt', 'w+')
f.write(ascii(json.dumps(msg)))
也没有区别。
所以,我很确定RequestParser()
试图变得太聪明了,无法理解非Unicode输入。
谢谢!
好吧,我终于找到了解决方法。感谢@lenz为我解决这个问题。似乎reqparse
错误地假定每个字符串参数都以UTF-8的形式出现。因此,当它看到非Unicode输入字段(以及其他Unicode字段!)时,它将尝试将其加载为Unicode并失败。结果,所有字符均为U+FFFD
(替换字符)。
因此,要访问该非Unicode字段,我做了以下技巧。
首先,我使用get_data()
加载原始数据,使用cp1251对其进行解码,并使用简单的正则表达式进行解析。
raw_data = request.get_data()
contents = raw_data.decode('windows-1251')
match = re.search(r'(?P<delim>--\w+\r?\n)Content-Disposition: form-data; name=\"text\"\r?\n(.*?)(?P=delim)', contents, re.MULTILINE | re.DOTALL)
text = match.group(2)
不是最漂亮的解决方案,但是可以。