【问题标题】:How to download binary file using requests [duplicate]如何使用请求下载二进制文件[重复]
【发布时间】:2019-04-05 16:42:33
【问题描述】:

我正在尝试下载一个二进制文件并将其以其原始名称保存在磁盘上 (linux)。

有什么想法吗?

import requests

params = {'apikey': 'xxxxxxxxxxxxxxxxxxx', 'hash':'xxxxxxxxxxxxxxxxxxxxxxxxx'}
response = requests.get('https://www.test.com/api/file/download', params=params)
downloaded_file = response.content

if response.status_code == 200:
    with open('/tmp/', 'wb') as f:
        f.write(response.content)

【问题讨论】:

  • 这里有一个更好的:stackoverflow.com/a/16696317/10408316
  • 我更喜欢处理请求
  • 这是请求。看看链接。你要做的就是将requests.getstream参数设置为True,然后分块读取流并写入二进制文件(open("file", "wb"
  • 我知道如何下载文件,只需要知道如何将其保存为原始名称
  • 你说的原名是什么意思?

标签: python


【解决方案1】:

根据您在 cmets 中的说明,您的问题是您想保留文件的原始名称。

如果 URL 指向原始二进制数据,那么 URL 的最后一部分将是它的“原始名称”,因此您可以通过如下方式解析 URL 来获得它:

local_filename = url.split('/')[-1]

为了将其付诸实践,并考虑到问题的上下文,这里是完全符合您需要的代码,它是从another SO question 复制而来的:

local_filename = url.split('/')[-1]
# NOTE the stream=True parameter
r = requests.get(url, stream=True)
with open(local_filename, 'wb') as f:
    for chunk in r.iter_content(chunk_size=1024): 
        if chunk: # filter out keep-alive new chunks
            f.write(chunk)
            #f.flush() commented by recommendation from J.F.Sebastian
return local_filename

无法将此作为评论发布,因此必须将其放在答案中。我希望我已经足够清楚了。如果您对代码有任何问题,请告诉我。当问题解决后,也请通知我,以便我可以删除它,因为它已经得到了回答。

编辑

这是您的代码的一个版本:

import requests

url = 'https://www.test.com/api/file/download'
params = {'apikey': 'xxxxxxxxxxxxxxxxxxx', 'hash':'xxxxxxxxxxxxxxxxxxxxxxxxx', 'stream':True}
response = requests.get(url, params=params)

local_filename = url.split('/')[-1]
totalbits = 0
if response.status_code == 200:
    with open(local_filename, 'wb') as f:
        for chunk in response.iter_content(chunk_size=1024):
            if chunk:
                totalbits += 1024
                print("Downloaded",totalbits*1025,"KB...")
                f.write(chunk)

注意:如果您不希望它显示进度,只需删除第 15 行的printstatement。这是使用此 url 测试的:https://imagecomics.com/uploads/releases/_small/DeadRabbit-02_cvr.jpg,它似乎工作得很好。同样,如果您有任何问题,请在下方评论。

【讨论】:

  • 你能用我的代码展示一个例子吗(在问题中)?
  • @bugnet17 抱歉回复晚了,我已经为您在问题中的代码制作了一个版本并发布了它。使用此 url 测试了代码:imagecomics.com/uploads/releases/_small/DeadRabbit-02_cvr.jpg 图像已正确下载到我的桌​​面,并具有相同的原始名称。
  • @Dennis Patterson 您在计算中混淆了位和字节。对于当今的典型文件大小和带宽而言,1KB 的缓冲区大小也非常小:您不想为了每秒打印几次进度而阻塞下载!此外,您乘以 1025 而不是除以 1025 来获得下载的总字节数:这背后的逻辑是什么?
  • (P.S:另外,最好只累积 len(chunk) 以确保下载的总字节数的准确性,或者至少调整最后一个块的长度)
  • 要添加,您可能需要执行 os.fsync(f.fileno()) 以确保所有缓冲区为空。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-30
  • 2018-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多