使用 httr 提取二进制附件

Extract binary attachment using httr

提问人:fsumathguy 提问时间:8/15/2023 更新时间:8/16/2023 访问量:74

问:

我到处寻找这个问题的答案,但我是空的。我向 API 发出 POST 请求,它返回一个对象 。Content-Type: application/xop+xml

响应如下所示:

Response [https://...]
  Date: 2023-08-14 18:18
  Status: 200
  Content-Type: multipart/related; type="application/xop+xml"; boundary="uuid:0ca94e9c-b817-4e87-9628-656cdd58be68"; start="<[email protected]>"; start-info="text/xml"
  Size: 18.3 MB
<BINARY BODY>

在这种情况下,附件应该是 .zip 文件,但我不知道如何提取它。我尝试使用将响应的内容保存到文件中,但生成的文件无法打开。writeBin

我能够在这里获得有关内容的更多信息:

"Content-Type: application/octet-stream"                                                                                                                                                                                                                                                                                                                                                                                                                    
"Content-Transfer-Encoding: binary"                                                                                                                                                                                                                                                                                                                                                                                                                         
"Content-ID: <565bcd99-ad2d-41c4-ac57-16f1[email protected]>"                                                                                                                                                                                                                                                                                                                                                                                      
"Content-Disposition: attachment;name=\"tmp12345.zip\"" 

由于 API 需要身份验证,我无法提供可重现的示例,但我希望有人能给我一个关于如何成功提取此 zip 文件的提示。

r httr rcurl

评论

0赞 MrFlick 8/15/2023
你的代码到底是什么样子的?你是怎么打电话的?你曾经获取过内容吗?这些额外的标头从何而来?如果您无法提供可重现的示例,此 API 是否至少记录在某个公开可用的位置?writeBinhttr::content()
0赞 margusl 8/15/2023
您可以使用 将响应正文写入磁盘,即类似httr::write_disk()POST("yoursecret.api", ..., write_disk("tmp.zip"))
0赞 fsumathguy 8/15/2023
我忘了提到我也尝试使用,但它也没有用。文件已创建,但似乎已损坏。@MrFlick - 我用过.我不相信 API 文档是公开的。在我的搜索中,似乎此内容的格式很特殊,而不仅仅是一团二进制数据。这里有点解释:ibm.com/docs/en/cics-ts/5.3?topic=data-mtomxop-soapwrite_disk()writeBin(httr::content(r), "c:/temp/data.zip")
0赞 MrFlick 8/15/2023
的输出是什么?它是从可读的东西开始的吗?httr 似乎不需要多部分返回值。您可能需要自己解析内容,特别是如果您只想提取部分响应。根据该链接,数据应在响应中进行 base64 编码。您可以使用标头中报告的边界来分析不同的多部分部分。httr::content(..., as="text")
0赞 fsumathguy 8/15/2023
您询问的输出实际上是我从中获取其他标头信息的地方。所以这很有帮助,但我仍然有点坚持如何进行。我同意我需要使用边界来解析,但我不清楚如何做到这一点,因为它是二进制或 base64。

答:

2赞 fsumathguy 8/16/2023 #1

我想出了解决这个问题的方法,尽管它可能不是最好的。在上面@MrFlick评论之后,我开始研究搜索/解析原始数据的向量。我遇到了 grepRaw 函数,它被证明非常有用。就我而言,API 提供的“边界”并不是那么有用,因为即使进入该边界,仍然需要处理标头(也许有一种更优雅的方法)。我的解决方案基本上是这样的:

v = content(response)
si = grepRaw(".zip", v) + 9
ei = grepRaw("--uuid", v, all = T)[3] - 1   #uuid appears three times
bytes = raw[si:ei]
writeBin(bytes, file_name)

对于其他任何寻找答案的人,我建议你做类似的事情,通过反复试验(以及 rawToChar),你可以将响应的哪些部分包含感兴趣的二进制数据归零。不漂亮,但有效。

如果有人想出更优雅的解决方案,请随时在这里分享。