使用Python3下载ZIP文件并将其在内存中解压缩

18

我想从互联网下载一个zip文件并解压它。

我宁愿使用requests,不想写入磁盘。

我知道如何在Python2中做到这一点,但对于Python3.3,我一无所知。显然,zipfile.Zipfile需要一个类似文件的对象,但我不知道如何从requests返回的内容中获取它。

如果您知道如何使用urllib.request完成此操作,我也很想看看您是如何实现的。

3个回答

41

我找到了如何做到这一点:

request = requests.get(url)
file = zipfile.ZipFile(BytesIO(request.content))

我缺少的是:

  • 应该使用 request.content 来访问字节数据
  • io.BytesIO 是正确的用于 bytes 的文件对象。

我同意,我的表述似乎涉及到某种黑魔法 :) 感谢您的澄清! - user1720740
嗨,这个解决方案也兼容Python 2.7吗? - Anurag-Sharma
2
为了更清晰地理解@aonbyte的答案,可以使用以下代码:zipDocument = zipfile.ZipFile(io.BytesIO(request.content)) 然后提取/保存它:zipDocument.extractall() - Michal Skop

8

这里有另一种方法,可以避免您安装requests:

    r = urllib.request.urlopen(req)
    with zipfile.ZipFile(BytesIO(r.read())) as z:
        print( z.namelist() )

3
我会给你点赞,至少不会是小于 0 的数字。我认为这是一个不错的回答,虽然我更喜欢使用 requests :)。 - zapatilla
我喜欢这个答案 - 它避免了在简单用例(例如从GitHub发布中下载资产文件)中需要安装requests库的要求。 - Bojan P.

6
使用Requests库可以非常简单地完成这个操作。
import requests, zipfile, StringIO
response = requests.get(zip_file_url)
zipDocument = zipfile.ZipFile(StringIO.StringIO(response.content))

使用String.IO,您可以为响应的内容属性创建类似文件的对象。 如果您想要提取到目录,可以使用ZipFile的extractall()函数。
zipDocment.extractall()

Python3 中没有 StringIO.StringIO。可以使用 io.StringIO。但在我的安装中,这种方法失败了。也许我的安装有问题: TypeError: initial_value 必须是 str 或 None,而不是 bytes。 - user1720740
2
-1,在Python 3中无法正常工作 - StringIO需要一个str,而ZipFileresponse.content都需要bytes。使用io.ByteIO即可。 - dbr
答案和@dbr的评论中有错别字:应该是zipDocument.extractall()io.BytesIO。即,zipfile.ZipFile(io.BytesIO(response.content))(注意:无法编辑答案)。 - Michal Skop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接