csv.reader 从请求流中读取:迭代器应该返回字符串,而不是字节

mda*_*acz 5 python csv django python-3.x python-requests

我想响应流中,以csv.reader使用requests.get(url, stream=True) 来处理相当大的数据文件。我的代码与python2.7. 这是代码:

response = requests.get(url, stream=True)
ret = csv.reader(response.iter_lines(decode_unicode=True), delimiter=delimiter, quotechar=quotechar,
    dialect=csv.excel_tab)
for line in ret:
    line.get('name')
Run Code Online (Sandbox Code Playgroud)

不幸的是,在迁移到 python3.6 后,出现以下错误:

_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)
Run Code Online (Sandbox Code Playgroud)

我试图找到一些包装器/装饰器,可以将response.iter_lines()迭代器的结果从字节转换为字符串,但没有运气。我已经尝试使用iopackage 和codecs. Usingcodecs.iterdecode不会按行拆分数据,它可能只是按 拆分chunk_size,在这种情况下csv.reader以以下方式抱怨:

_csv.Error: new-line character seen in unquoted field - do you need to open the file in universal-newline mode?
Run Code Online (Sandbox Code Playgroud)

Jim*_*ard 7

我猜你可以把它包装在 a 中,genexp然后将解码的行提供给它:

from contextlib import closing

with closing(requests.get(url, stream=True)) as r:
    f = (line.decode('utf-8') for line in r.iter_lines())
    reader = csv.reader(f, delimiter=',', quotechar='"')
    for row in reader:
        print(row)
Run Code Online (Sandbox Code Playgroud)

3.5此使用一些示例数据会关闭csv.reader,输入给它的每一行都是decodedgenexp 中的第一行。另外,我使用closingfrom contextlibas通常建议自动close响应。