在Python中解析多部分请求字符串

Sam*_*ony 2 python aws-lambda aws-api-gateway

我有这样的字符串

"--5b34210d81fb44c5a0fdc1a1e5ce42c3\r\nContent-Disposition: form-data; name=\"author\"\r\n\r\nJohn Smith\r\n--5b34210d81fb44c5a0fdc1a1e5ce42c3\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example2.txt\"\r\nContent-Type: text/plain\r\nExpires: 0\r\n\r\nHello World\r\n--5b34210d81fb44c5a0fdc1a1e5ce42c3--\r\n"
Run Code Online (Sandbox Code Playgroud)

我也有其他标题可用的请求标头。

如何使用Python3轻松解析?

我正在通过API网关在AWS Lambda中处理文件上传,请求主体和标头可通过Python dict使用。

关于堆栈溢出还有其他类似的问题,但是大多数都假设使用requests模块或其他模块,并且期望请求详细信息采用特定的对象或格式。

注意:我知道可以将用户上传到S3并触发Lambda,但是在这种情况下,我故意选择不这样做。

Sam*_*ony 6

可以通过使用类似的东西来解析

from requests_toolbelt.multipart import decoder
multipart_string = "--ce560532019a77d83195f9e9873e16a1\r\nContent-Disposition: form-data; name=\"author\"\r\n\r\nJohn Smith\r\n--ce560532019a77d83195f9e9873e16a1\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example2.txt\"\r\nContent-Type: text/plain\r\nExpires: 0\r\n\r\nHello World\r\n--ce560532019a77d83195f9e9873e16a1--\r\n"
content_type = "multipart/form-data; boundary=ce560532019a77d83195f9e9873e16a1"
decoder.MultipartDecoder(multipart_string, content_type)
Run Code Online (Sandbox Code Playgroud)

  • 希望您应该发现`multipart / form-data`就足以作为`content_type` ...,因为边界字符串不是您必须自己寻找的东西,并且通常随每条消息而变化。 (2认同)
  • 谢谢(你的)信息。似乎标头中的边界实际上是MultipartDecoder解析该多部分字符串所必需的。我最终实现了它以使用正确的mime类型,这在AWS Lambda提供的其他变量中仍然可用。 (2认同)

ces*_*ves 5

扩展 sam-anthony' 答案(我必须对其进行一些修复才能在 python 3.6.8 上工作):

from requests_toolbelt.multipart import decoder

multipart_string = b"--ce560532019a77d83195f9e9873e16a1\r\nContent-Disposition: form-data; name=\"author\"\r\n\r\nJohn Smith\r\n--ce560532019a77d83195f9e9873e16a1\r\nContent-Disposition: form-data; name=\"file\"; filename=\"example2.txt\"\r\nContent-Type: text/plain\r\nExpires: 0\r\n\r\nHello World\r\n--ce560532019a77d83195f9e9873e16a1--\r\n"
content_type = "multipart/form-data; boundary=ce560532019a77d83195f9e9873e16a1"

for part in decoder.MultipartDecoder(multipart_string, content_type).parts:
  print(part.text)

John Smith
Hello World
Run Code Online (Sandbox Code Playgroud)

您所要做的就是通过pip install requests-toolbelt --target= 安装此库。然后将其与您的 lambda 脚本一起上传

这是一个工作示例:

from requests_toolbelt.multipart import decoder

def lambda_handler(event, context):

    content_type_header = event['headers']['Content-Type']

    body = event["body"].encode()

    response = ''
    for part in decoder.MultipartDecoder(body, content_type_header).parts:
      response += part.text + "\n"

    return {
        'statusCode': 200,
        'body': response
    }
Run Code Online (Sandbox Code Playgroud)

这应该足以让您的依赖项被识别。如果不是,请尝试在 zip 中使用“/python/lib/python3.6/site-packages”文件结构,并在根目录下使用 python 脚本”