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

时间:2016-09-21 14:39:44

标签: python django python-3.x csv python-requests

我正在尝试使用csv.reader将响应流式传输到requests.get(url, stream=True)以处理相当大的数据Feed。我的代码与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')

不幸的是,在迁移到python3.6后,我收到了以下错误:

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

我试图找到一些将response.iter_lines()迭代器的结果从字节转换为字符串的包装器/装饰器,但是没有运气。 我已经尝试使用io包和codecs。使用codecs.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?

1 个答案:

答案 0 :(得分:4)

我猜你可以将它包装在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)

使用3.5中的一些示例数据会关闭csv.reader,每个输入到它的行都是genexp中的decoded。另外,我使用closing中的contextlib generally suggested来{{3}}自动close响应。