我编写了一个脚本,它点击一个 URL 并下载一个 zip 文件,并将其解压缩。现在我在解析解压后得到的 CSV 文件时遇到问题。
import csv
from requests import get
from io import BytesIO
from zipfile import ZipFile
request = get('https://example.com/some_file.zip')
zip_file = ZipFile(BytesIO(request.content))
files = zip_file.namelist()
with open(files[0], 'r') as csvfile:
csvreader = csv.reader(csvfile)
for row in csvreader:
print(row)
参见上面@joe-heffer的答案:https://stackoverflow.com/a/53187751/223424
当您执行
files = zip_file.namelist()
时,您只需列出 zip 存档中的文件名称即可;这些文件尚未从 zip 中提取,您无法像您正在做的那样将它们 open
作为 local 文件。
ZipFile.open
直接从 zip 文件中读取数据流。
所以这应该有效:
zip_file = ZipFile(BytesIO(request.content))
files = zip_file.namelist()
with zip_file.open(files[0], 'r') as csvfile:
csvreader = csv.reader(csvfile)
...
response = requests.get(url)
with io.BytesIO(response.content) as zip_file:
with zipfile.ZipFile() as zip_file:
# Get first file in the archive
for zip_info in zip_file.infolist():
logger.debug(zip_info)
# Open file
with zip_file.open(zip_info) as file:
# Load CSV file, decode binary to text
with io.TextIOWrapper(file) as text:
return csv.DictReader(text)
看起来您还没有导入
csv
模块。 尝试将 import csv
放在导入的顶部。
所以。经过几个小时的搜索和尝试,我终于得到了一些有用的东西。这是我的脚本。
所以我的需求是:
#!/bin/env python
from io import BytesIO
from zipfile import ZipFile
import requests
import re
import sys
# define url value
url = "https://whateverurlyouneed"
# Define string to be found in the file name to be extracted
filestr = "anystring"
# Define string to be found in URL
urlstr = "anystring"
# Define regex to extract URL
regularex = r"(?i)\b((?:https?://|www\d{0,3}[.]|[a-z0-9.-]+[.][a-z]{2,4}/)(?:[^\s()<>]+|(([^\s()<>]+|(([^\s()<>]+)))))+(?:(([^\s()<>]+|(([^\s()<>]+))))|[^\s`!()[]{};:'\".,<>?«»“”‘’]))"
# download zip file
content = requests.get(url)
# Open stream
zipfile = ZipFile(BytesIO(content.content))
# Open first file from the ZIP archive containing
# the filestr string in the name
data = [zipfile.open(file_name) for file_name in zipfile.namelist() if filestr in file_name][0]
# read lines from the file. If csv found, print URL and exit
# This will return the 1st URL containing CSV in the opened file
for line in data.readlines():
if urlstr in line.decode("latin-1"):
urls = re.findall(regularex,line.decode("latin-1"))
print([url[0] for url in urls])
break
sys.exit(0)