gpt4 book ai didi

python - 使用 Python 请求发布二进制(视频)文件

转载 作者:太空宇宙 更新时间:2023-11-04 09:03:40 26 4
gpt4 key购买 nike

我有一段 PHP 代码可以将二进制文件上传到我没有 shell 访问权限的远程服务器。 PHP代码是:

function upload($uri, $filename) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uri);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('file' => '@' . $filename));
curl_exec($ch);
curl_close($ch);
}

这导致标题如下:

HTTP/1.1
Host: XXXXXXXXX
Accept: */*
Content-Length: 208045596
Expect: 100-continue
Content-Type: multipart/form-data; boundary=----------------------------360aaccde050

我正在尝试使用请求将其移植到 python,但我无法让服务器接受我的 POST。我已经尝试了各种使用 requests.post 的方式,但标题不会模仿上面的内容。

这将成功地将二进制文件传输到服务器(可以通过观察 wireshark 来判断)但是因为 header 不是服务器所期望的,所以它被拒绝了。不过,response_code 是 200。

files = {'bulk_test2.mov': ('bulk_test2.mov', open('bulk_test2.mov', 'rb'))}
response = requests.post(url, files=files)

请求代码产生一个 header :

HTTP/1.1
Host: XXXX
Content-Length: 160
Content-Type: multipart/form-data; boundary=250852d250b24399977f365f35c4e060
Accept-Encoding: gzip, deflate, compress
Accept: */*
User-Agent: python-requests/2.2.1 CPython/2.7.5 Darwin/13.1.0

--250852d250b24399977f365f35c4e060
Content-Disposition: form-data; name="bulk_test2.mov"; filename="bulk_test2.mov"


--250852d250b24399977f365f35c4e060--

关于如何使请求匹配 PHP 代码生成的 header 有什么想法吗?

最佳答案

有两个很大的区别:

  1. PHP 代码发布一个名为 file 的字段,您的 Python 代码发布一个名为 bulk_test2.mov 的字段。

  2. 您的 Python 代码发布了一个 文件。 Content-Length header 为 160 字节,恰好是多部分边界和 Content-Disposition 部分 header 占用的空间量。 bulk_test2.mov 文件确实是空的,或者您尝试多次发布文件而没有倒带或重新打开文件对象。

要解决第一个问题,请使用 'file' 作为 files 字典中的键:

files = {'file': open('bulk_test2.mov', 'rb')}
response = requests.post(url, files=files)

使用打开的文件对象作为值;在这种情况下,requests 将直接从文件对象中获取文件名。

第二个问题只有您才能解决。确保在重复发布时不要重复使用文件。重新打开,或使用 files['file'].seek(0) 将读取位置倒回到开始位置。

Expect: 100-continue header 是一个可选的客户端功能,它要求服务器 confirm that the body upload can go ahead ;它不是必需的 header ,任何未能发布您的文件对象都不会是由于请求是否使用此功能。如果 HTTP 服务器在您不使用此功能的情况下出现错误行为,则它违反了 HTTP RFC,您将遇到更大的问题。这肯定不是 requests 可以为您解决的问题。

如果您设法发布实际文件数据,Content-Length 中的任何微小变化都是由于 Python 和 PHP 之间的(随机)边界长度不同所致。这是正常,而不是上传问题的原因,除非您的目标服务器严重损坏。再次强调,不要试图用 Python 修复这种问题。

但是,我假设您忽略了一些更简单的事情。例如,服务器可能会将某些 User-Agent header 列入黑名单。您可以使用 Session object 清除一些默认 header requests 集:

files = {'file': open('bulk_test2.mov', 'rb')}
session = requests.Session()
del session.headers['User-Agent']
del session.headers['Accept-Encoding']
response = session.post(url, files=files)

看看这是否有所作为。

如果服务器因为无法处理HTTP persistent connections而无法处理你的请求,您可以尝试将 session 用作上下文管理器以确保关闭所有 session 连接:

files = {'file': open('bulk_test2.mov', 'rb')}
with requests.Session() as session:
response = session.post(url, files=files, stream=True)

你可以添加:

response.raw.close()

为了好的措施。

关于python - 使用 Python 请求发布二进制(视频)文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23018521/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com