我正在尝试从Python 3中从给定网址检索到的csv生成记录。
鉴于urlopen
返回字节模式文件对象但csv.DictReader
需要文本模式文件对象,我必须将urlopen
文件对象包装在TextIOWrapper
中(使用utf-8解码)。现在,不幸的是,我陷入了两个不受欢迎的选择之中:
1)TextIOWrapper
不支持seek
,因此在检查csv_file
标题后,我无法重置Sniffer
生成器。
2)如果我没有seek
回到0,我会截断前18条记录。
如何修改以下代码,以便它可以检查标题并从urlopen
个调用中获取所有记录?
我尝试了什么?
读取URL两次:一次检查标题,第二次生成csv记录。这似乎不是最理想的。
跳过下面前18条记录的代码。取消注释第12行以生成seek
错误。
import csv
import io
import urllib.request
def read_url_csv(url, fieldnames=None, transform=None):
if transform is None:
transform = lambda x, filename, fieldnames: x
with urllib.request.urlopen(url) as csv_binary:
csv_file = io.TextIOWrapper(csv_binary, "utf-8")
has_header = csv.Sniffer().has_header(csv_file.read(1024))
#csv_file.seek(0)
reader = csv.DictReader(csv_file, fieldnames=fieldnames)
if has_header and fieldnames is not None: #Overwriting
next(reader)
for record in reader:
yield transform(record, url, fieldnames)
答案 0 :(得分:0)
StringIO支持寻求。
csv_file = io.StringIO(io.TextIOWrapper(csv_binary, "utf-8").read())
has_header = csv.Sniffer().has_header(csv_file.read(1024))
csv_file.seek(0)