Python 3 - 在测试标题

时间:2018-06-04 13:49:28

标签: python-3.x

我正在尝试从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)

1 个答案:

答案 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)