我尝试从FTP服务器读取CSV文件并在应用引擎上解析它。
我可以访问该文件并将其读取到StringIO
但是当我尝试遍历文件行时,它只是遍历每个字符而不是行。不知道我在这里做错了什么:
ftp = FTP('ftp.mydomain.com', 'username', 'pwd')
ftp.set_pasv(True)
r = StringIO()
ftp.retrbinary('RETR test.csv', r.write)
csvfile = csv.reader(r.getvalue(), delimiter=',')
for line in csvfile:
print line
最终会出现这样的事情:
['O']
['R']
['D']
['E']
['R']
['N']
['O']
['', '']
['O']
['R']
['D']
['E']
['R']
['D']
['A']
['T']
['E']
['', '']
['I']
['N']
['V']
['O']
['I']
['C']
['E']
['N']
['O']
['', '']
...
执行此操作的正确方法是什么,并正确解析FTP中的文件,以便csv
模块可以正确读取它?
答案 0 :(得分:3)
在换行符上拆分长字符串; csv.reader()
期望 iterable ,其中每次迭代都会产生一条线。你给它一个字符串,迭代就是单个字符然后:
csvfile = csv.reader(r.getvalue().splitlines(), delimiter=',')
您没有显示导入StringIO()
的方式。如果它是 python版本(from StringIO import StringIO
),您可以直接回到起点并直接在中传递:
r.seek(0)
csvfile = csv.reader(r, delimiter=',')
答案 1 :(得分:2)
对于Python 3.x和csv.DictReader:
bio = io.BytesIO()
resp = ftp.retrbinary("RETR " + filename, bio.write)
bio.seek(0)
csv_data = csv.DictReader(io.TextIOWrapper(bio, newline=None), delimiter=',')
for row in data:
...
我花了一段时间才找到这个解决方案,所以我发布了它。我找到的答案没有解决问题,以保持数据的方式使DictReader
满意。
如果您不关心DictReader
,可能会解决以下问题:
sio = io.StringIO()
resp = ftp.retrlines("RETR " + filename, sio.write)
sio.seek(0)
并非您需要retrlines
,因为Python3 StringIO
不接受二进制文件。