从 zip 打开文件而不用 Python 解压?

Posted

技术标签:

【中文标题】从 zip 打开文件而不用 Python 解压?【英文标题】:Open file from zip without extracting it in Python? 【发布时间】:2018-03-28 11:05:42 【问题描述】:

我正在编写一个脚本,该脚本使用 tje 请求库从 URL 获取 zip 文件。该 zip 文件包含一个 csv 文件。我正在尝试读取该 csv 文件而不保存它。但是在解析时它给了我这个错误:_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)

import csv
import requests
from io import BytesIO, StringIO
from zipfile import ZipFile

response = requests.get(url)
zip_file = ZipFile(BytesIO(response.content))
files = zip_file.namelist()
with zip_file.open(files[0]) as csvfile:
    csvreader = csv.reader(csvfile)

    # _csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)

    for row in csvreader:
        print(row)

【问题讨论】:

Convert binary input stream to text mode的可能重复 ZipFile.open 返回二进制流,但 csv.reader 需要文本流。您必须添加一个将二进制数据解码为文本的包装器。 【参考方案1】:

试试这个:

import pandas as pd
import requests
from io import BytesIO, StringIO
from zipfile import ZipFile

response = requests.get(url)
zip_file = ZipFile(BytesIO(response.content))
files = zip_file.namelist()
with zip_file.open(files[0]) as csvfile:   
    print(pd.read_csv(csvfile, encoding='utf8', sep=","))

【讨论】:

【参考方案2】:

正如@Aran-Fey 所暗示的那样:

import zipfile
import csv
import io

with open('/path/to/archive.zip', 'r') as f:
    with zipfile.ZipFile(f) as zf:
        csv_filename = zf.namelist()[0]  # see namelist() for the list of files in the archive
        with zf.open(csv_filename) as csv_f:
            csv_f_as_text = io.TextIOWrapper(csv_f)
            reader = csv.reader(csv_f_as_text)

csv.reader(和csv.DictReader)需要以文本模式打开的类似文件的对象。通常,当在'r' 模式下简单地使用open(...)ing 文件时,这不是问题,正如Python 3 文档所说,文本模式是默认模式:“默认模式是'r'(打开以读取文本,'rt 的同义词')”。但是如果你在ZipFile 上尝试rtopen,你会看到一个错误:ZipFile.open() requires mode "r" or "w":

        with zf.open(csv_filename, 'rt') as csv_f:
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
...    
ValueError: open() requires mode "r" or "w"

这就是io.TextIOWrapper 的用途——将字节流包装成文本可读,动态解码它们。

【讨论】:

以上是关于从 zip 打开文件而不用 Python 解压?的主要内容,如果未能解决你的问题,请参考以下文章

怎么从zip里提取文件 Python

python怎样压缩和解压缩ZIP文件

用Java制作打rar压缩包程序

python怎样压缩和解压缩ZIP文件

如何用7-Zip 把文件压缩成rar文件???

压缩文件zip与rar有啥区别?