我正在使用请求库编写Web Service Client。我在multipart / form-data中获取包含文件和text-json的数据。我不知道如何解析它。是否有一个适当的库来解析python中的multipart / form-data格式,还是应该自己编写解析器?
我的代码:
data = {
"prototypeModel" :('prototypeModel', open(prototypeModel, 'rb'), 'application/octet-stream', {'Expires': '0'}),
"mfcc_1" : ('mfcc', open(mfcc_1, 'rb'), 'application/octet-stream', {'Expires': '0'}),
"mfcc_2" : ('mfcc', open(mfcc_2, 'rb'), 'application/octet-stream', {'Expires': '0'}),
"mfcc_3" : ('mfcc', open(mfcc_3, 'rb'), 'application/octet-stream', {'Expires': '0'}),
}
print( '---------------------- start enroll ----------------------')
testEnrollResponse = requests.post(server+sessionID, files = data, json = declaredParameters)
B' \ r \ N - c00750d1-8ce4-4d29-8390-b50bf02a92cc \ r \ nContent处置: 形式数据;名称=" playbackHash" \ r \ nContent型: 应用/八位字节流\ r \ n \ r \ n \ X16 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ x00serialization ::归档\ n \ X00 \ X04 \ X08 \ X04 .... X00 \ x00R \ X94 \ x9bp \ x8c \ X00 \ r \ n - c00750d1-8ce4-4d29-8390-b50bf02a92cc \ r \ nContent处置: 形式数据;名称=" usersMFCC" \ r \ nContent型: 应用/八位字节流\ r \ n \ r \ n \ X16 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ x00serialization ::归档\ n \ X00 \ X04 \ X08 \ X04 \ X08 \ X01 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ X00 \ XF8 \ X16 \ X00 \ X00 \ X00 \ X00 \ X00 \ x00u \ XBD \ XB4 / \ xda1 \ XEA \ XBF \ X0F \固定的\ XA2< \ xc9 \ XF8 \ XE7 \ XBF?\ XD5 \ xf06u \ XE7 \ XF0 \ XBF \ XD 4 \ x8d \ XD 4 \ xa1F \ XBE \ X03 @ \ x85X!\ X19 \ xd8A \ X06 @ \ x8co \ XF7 \ r .....
?X80 \ xd9 \ x95Yxn \ XD0 \ r \ n - c00750d1-8ce4-4d29-8390-b50bf02a92cc \ r \ nContent处置: 形式数据; name =" scoreAndStatus" \ r \ nConContent-Type:application / json; 字符集= UTF-8 \ r \ n \ r \ N {" lexLikelihood":1.544479046897232" overalScore值": - 南," playbackLikelihood": - INF,& #34;状态" {"的errorCode":0,"的errorMessage":""}} \ r \ N - c00750d1-8ce4-4d29 -8390-b50bf02a92cc - \ r \ n'
我用"替换了更多的二进制数据。 ....."
答案 0 :(得分:12)
如果您收到multipart/form-data
回复,可以使用requests-toolbelt
库进行解析,如下所示:
$ pip install requests-toolbelt
安装后
from requests_toolbelt.multipart import decoder
testEnrollResponse = requests.post(...)
multipart_data = decoder.MultipartDecoder.from_response(testEnrollResponse)
for part in multipart_data.parts:
print(part.content) # Alternatively, part.text if you want unicode
print(part.headers)
答案 1 :(得分:3)
Flask的代码示例,使用https://github.com/defnull/multipart
import multipart as mp
from multipart import tob
try:
from io import BytesIO
except ImportError:
from StringIO import StringIO as BytesIO
@app.route('/', methods=["GET","POST"])
def index():
...
elif flask.request.method == "POST":
data = flask.request.data
s = data.split("\r")[0][2:]
p = mp.MultipartParser(BytesIO(tob(data)),s)
blob = p.parts()[0].value
f = open("file.bin","wb")
f.write(blob.encode("latin-1"))
f.close()
答案 2 :(得分:2)
下面是working example的解析多部分数据。您可以在交互式python提示符下尝试一下。
import email
msg = email.message_from_string('''\
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=" XXXX"
-- XXXX
Content-Type: text/plain
-- XXXX
Content-Type: text/plain
-- XXXX--
''')
msg.is_multipart()
一旦知道了它在系统上的正常运行,就可以根据POST数据构建自己的电子邮件,并以相同的方式对其进行解析。如果将原始post body作为字符串,则可以在请求标头中找到其余的必要信息。为了清楚起见,我在此处添加了缩进,因此块字符串中不应包含多余的缩进。
epost_data = '''\
MIME-Version: 1.0
Content-Type: %s
%s''' % (self.headers['content-type'], post_data)
msg = email.message_from_string(post_data)
if msg.is_multipart():
for part in msg.get_payload():
name = part.get_param('name', header='content-disposition')
filename = part.get_param('filename', header='content-disposition')
# print 'name %s' % name # "always" there
# print 'filename %s' % filename # only there for files...
payload = part.get_payload(decode=True)
print payload[:100] # output first 100 characters
第一个%s
将被替换为内容类型,第二个将被post_data
替换。然后,您可以将有效负载写入文件等。
请谨慎考虑保存文件的安全性。您可能无法信任发布的文件名,例如,在某些Web服务器上,它可能以../../filename.sh
开头,因此,如果您尝试写入/my-folder/../../filename.sh
,则攻击者可能会将恶意文件放置在文件名之外。您尝试存储文件的位置。还建议在信任文件本身之前对文件作为允许的类型进行强力验证。您不想让攻击者覆盖系统上的任何文件。