如何使用请求下载文件

Posted

技术标签:

【中文标题】如何使用请求下载文件【英文标题】:How to download a file using requests 【发布时间】:2021-06-04 07:50:52 【问题描述】:

我正在使用请求库从 URL 下载文件。这是我的代码

for tag in soup.find_all('a'):
    if '.zip' in str(tag):
        file_name = str(tag).strip().split('>')[-2].split('<')[0]
        link = link_name+tag.get('href')
        r = requests.get(link, stream=True)

        with open(os.path.join(download_path, file_name), 'wb') as fd:
            for chunk in r.iter_content(chunk_size=1024):
                if chunk:
                    fd.write(chunk)

然后我使用此代码解压缩文件

unzip_path = os.path.join(download_path, file_name.split('.')[0])

with zipfile.ZipFile(os.path.join(download_path, file_name), 'r') as zip_ref:
    zip_ref.extractall(unzip_path)

此代码查看提供的页面中是否有压缩文件,然后将压缩文件下载到目录中。然后它将使用zipFile 库解压缩文件。

这段代码的问题是有时下载不完整。因此,例如,如果压缩文件的长度为 312KB,则只会下载其中的一部分。然后我得到一个BadZipFile 错误。但有时整个文件都能正确下载。

我在没有流式传输的情况下尝试了同样的方法,甚至导致同样的问题。

如何检查是否所有块都已正确下载。

【问题讨论】:

你可以考虑时间模块的睡眠功能,以使程序睡眠几秒钟,以便在移动到提取部分之前完全下载文件吗? @AmineBTG 尝试在 unzip_path 之前添加 time.sleep(5)。但这似乎并不能解决问题。我应该在for chunk in r.iter_content(chunk_size=1024): 中添加睡眠吗? 尝试在没有流的情况下获取文件stream=False 并在没有块的情况下写入文件fd.write(r.content) 好的。你为什么要写块?收到请求后,为什么不一次性写入整个文件(stream = False)? 【参考方案1】:

也许这行得通:

r = requests.get(link)  
with open(os.path.join(download_path, file_name), 'wb') as fd:
    fd.write(r.content)

【讨论】:

这似乎也不是一直有效。我现在在 unzip_path 之前有一个time.sleep(5)。它只下载整个 315KB 中的 5Kb 检查返回码。是200? r.status_code 有时是 200,有时是 403。 如果没有隐私问题,可以发几个网址作为例子吗?

以上是关于如何使用请求下载文件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用请求下载二进制文件[重复]

使用Jmeter如何测试下载接口

如何使用请求测量下载速度和进度?

如何从 url 下载文件并使用 python 请求保留其名称和元数据

Express js:如何使用 POST 请求下载文件

如何将文件保存到在 REST URL 请求中下载的某个文件夹? [复制]