我已经为这个简单的问题苦苦挣扎了太久了,所以我想寻求帮助。我正在尝试从国立医学图书馆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?)
我想我应该使用字符串而不是字节?对于简单问题的任何帮助,以及对出了什么问题的解释,将不胜感激。
问题取决于urllib返回字节。作为证明,您可以尝试使用浏览器下载csv文件,然后将其作为常规文件打开,问题就消失了。
urllib
这里也解决了类似的问题。
可以解决使用适当的编码将字节解码为字符串的情况。例如:
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)可能更易于阅读。
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
请注意,出于相同的原因,也不会创建该列表。