Python不解压Zip直接读取CSV报_csv.Error的解决方法
解决直接读取Zip中CSV时的字节/文本模式错误
嘿,我之前也踩过这个坑!咱们来快速搞定这个问题~
问题根源
你遇到的_csv.Error: iterator should return strings, not bytes错误,核心原因是:ZipFile.open()返回的是二进制模式的文件对象,而csv.reader只能处理文本模式的迭代器——直接喂字节流肯定会报错。
两种解决方案
下面是两种可行的修复方式,你可以根据需求选择:
方案1:先解码字节为字符串,再用StringIO包装
这种方式适合小体积的CSV文件,操作直观:
import csv import requests from io import BytesIO, StringIO from zipfile import ZipFile # 替换成你的目标URL url = "https://example.com/your-file.zip" response = requests.get(url) zip_file = ZipFile(BytesIO(response.content)) # 从zip中筛选出CSV文件名(假设只有一个CSV) csv_filename = next(f for f in zip_file.namelist() if f.endswith('.csv')) with zip_file.open(csv_filename) as csv_binary: # 读取全部字节并解码为字符串(注意编码要匹配你的CSV,比如utf-8/gbk) csv_text = csv_binary.read().decode('utf-8') # 用StringIO把字符串包装成类文件对象 csv_reader = csv.reader(StringIO(csv_text)) # 测试读取行 for row in csv_reader: print(row)
方案2:用codecs实时转二进制流为文本流
这种方式更高效,不用一次性加载整个文件到内存,适合大CSV:
import csv import requests import codecs from io import BytesIO from zipfile import ZipFile url = "https://example.com/your-file.zip" response = requests.get(url) zip_file = ZipFile(BytesIO(response.content)) csv_filename = next(f for f in zip_file.namelist() if f.endswith('.csv')) with zip_file.open(csv_filename) as csv_binary: # 用codecs把二进制流包装成文本模式的reader text_stream = codecs.getreader('utf-8')(csv_binary) csv_reader = csv.reader(text_stream) for row in csv_reader: print(row)
关键注意点
- 编码匹配:一定要确认你的CSV文件实际编码(比如中文CSV常用gbk/utf-8-sig),解码时用对应编码,否则会出现乱码或解码错误。
- 多CSV处理:如果zip里有多个CSV,你需要调整
csv_filename的筛选逻辑,比如指定具体文件名。 - 分隔符问题:如果你的CSV用的不是逗号分隔,记得给
csv.reader加delimiter='\t'这类参数。
内容的提问来源于stack exchange,提问作者Magnotta




