从 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
上尝试rt
和open
,你会看到一个错误: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 解压?的主要内容,如果未能解决你的问题,请参考以下文章