小编典典

将URL中的.csv文件读入Python 3.x-_csv.Error:迭代器应返回字符串,而不是字节(您是否以文本模式打开文件?)

python

我已经为这个简单的问题苦苦挣扎了太久了,所以我想寻求帮助。我正在尝试从国立医学图书馆ftp站点的Python 3.3.2(在Windows7上)阅读期刊文章列表。日记文章位于.csv文件中。

我尝试了以下代码:

import csv
import urllib.request

url = "ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/file_list.csv"
ftpstream = urllib.request.urlopen(url)
csvfile = csv.reader(ftpstream)
data = [row for row in csvfile]

它导致以下错误:

Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
data = [row for row in csvfile]
File "<pyshell#4>", line 1, in <listcomp>
data = [row for row in csvfile]
_csv.Error: iterator should return strings, not bytes (did you open the file in text mode?)

我想我应该使用字符串而不是字节?对于简单问题的任何帮助,以及对出了什么问题的解释,将不胜感激。


阅读 181

收藏
2020-12-20

共1个答案

小编典典

问题取决于urllib返回字节。作为证明,您可以尝试使用浏览器下载csv文件,然后将其作为常规文件打开,问题就消失了。

这里也解决类似的问题。

可以解决使用适当的编码将字节解码为字符串的情况。例如:

import csv
import urllib.request

url = "ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/file_list.csv"
ftpstream = urllib.request.urlopen(url)
csvfile = csv.reader(ftpstream.read().decode('utf-8'))  # with the appropriate encoding 
data = [row for row in csvfile]

最后一行可能是:data = list(csvfile)可能更易于阅读。

顺便说一句,由于csv文件很大,因此它可能会变慢并且占用大量内存。也许最好使用发电机。

编辑: 使用由Steven Rumbalski提出的编解码器,因此不必读取整个文件进行解码。减少了内存消耗,提高了速度。

import csv
import urllib.request
import codecs

url = "ftp://ftp.ncbi.nlm.nih.gov/pub/pmc/file_list.csv"
ftpstream = urllib.request.urlopen(url)
csvfile = csv.reader(codecs.iterdecode(ftpstream, 'utf-8'))
for line in csvfile:
    print(line)  # do something with line

请注意,出于相同的原因,也不会创建该列表。

2020-12-20