Python 3.x 使用Flask RESTful解析非Unicode字符串

Python 3.x 使用Flask RESTful解析非Unicode字符串,python-3.x,flask,unicode,flask-restful,cyrillic,Python 3.x,Flask,Unicode,Flask Restful,Cyrillic,我有一个用Flask RESTful开发的webhook,它可以通过POST获得几个参数。 其中一个参数是非Unicode字符串,编码为cp1251 无法找到使用reqparse正确解析此参数的方法 以下是我的代码片段: parser = reqparse.RequestParser() parser.add_argument('text') msg = parser.parse_args() 然后,我将msg写入一个文本文件,如下所示: {"text": "\ufffd\ufffd\ufff

我有一个用Flask RESTful开发的webhook,它可以通过POST获得几个参数。 其中一个参数是非Unicode字符串,编码为cp1251

无法找到使用
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对其进行解码,并使用简单的regexp进行解析

 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)
raw\u data=request.get\u data()
内容=原始数据。解码('windows-1251')
match=re.search(r'(?P--\w+\r?\n)内容配置:表单数据;名称=\“text\”\r?\n(.*?(?P=delim)),内容,re.MULTILINE | re.DOTALL)
text=match.group(2)

虽然不是最漂亮的解决方案,但它很有效。

U+FFFD是替换字符。你能展示一下将文本写入磁盘的代码吗?另外,请显示
ascii(msg)
的输出,以查看问题是否发生在解析或编写过程中。我刚刚更新了问题。附加信息。您是否看到
reqparse
模块已弃用?如果这是
reqparse
中的错误,则可能无法修复。但我怀疑西里尔文字在早期阶段会被U+FFFD取代。您应该检查(或者在此处添加)值在
flask.request
对象上的直接外观,以及负载是如何由客户端发送的。@lenz我使用
request.get_data()
保存了原始请求,数据是正确的。所以我假设这是一个
reqparse
bug。。。是的,现在我看到它几乎被弃用了。将尝试解析原始数据或找到其他方法。谢谢你的帮助@lenz我刚刚让它工作了,在这里发布了解决方案作为答案。很高兴看到它工作了。我仍然认为,您应该确保不是客户机声明了错误的编码,如果可以的话,在这方面进行修复。