在Python 3.7中工作。
我目前正在从API (Qualys的API,获取报告)中提取数据。它返回一个字符串,其中包含CSV格式的所有报告数据,其中每个新行都使用'\r\n‘转义标记。
(即'foo,bar,stuff\r\n,more stuff,data,report\r\n等等\r\n‘)
我遇到的问题是将这个字符串正确地写入CSV文件。当在Excel中查看时,我尝试过的每一次代码迭代都会将数据单元格逐个写入,并将\r\n附加到字符串中所在位置的\r\n全部写在一行上,而不是换一行。
(即|foo|bar|stuff\r\n|更多stuff|data|report\r\n|etc|etc\r\n|)
我只是从2切换到3,所以我几乎可以肯定这是一个语法错误,或者是我对python 3如何处理新行分隔符或其他东西的理解错误,但即使在查看了文档、这里和博客帖子后,我也无法理解它,或者我总是遗漏了一些东西。
当前代码:
def dl_report(id, title):
data = {'action': 'fetch', 'id': id}
res = a.request('/api/2.0/fo/report/', data=data)
print(type(res)) #returns string
#input('pause')
f_csv = open(title,'w', newline='\r\n')
f_csv.write(res)
f_csv.close
但我也尝试过:
with open(title, 'w', newline='\r\n') as f:
writer = csv.writer(f,<tried encoding here, no luck>)
writer.writerows(res)
#anyone else looking at this, this didn't work because of the difference
#between writerow() and writerows()
我还尝试了多种方法来声明newline,例如:
newline=''
newline='\n'
etc...
以及沿着这些路线进行的各种其他迭代。任何建议或指导或者..。在这一点上,任何事情都会很棒。
编辑:
好的,我一直在做这件事,这是可行的:
def dl_report(id, title):
data = {'action': 'fetch', 'id': id}
res = a.request('/api/2.0/fo/report/', data=data)
print(type(res)) #returns string
reader = csv.reader(res.split(r'\r\n'), delimiter=',')
with open(title, 'w') as outfile:
writer = csv.writer(outfile, delimiter= '\n')
writer.writerow(reader)
但它很丑陋,而且确实会在输出CSV中产生错误(某些行(小于1%)不能解析为CSV行,可能是某个地方的格式错误……),但更令人担忧的是,当数据中出现"\“时,它的工作不稳定。
我真的对一个有效的解决方案感兴趣...好些了吗?更多的蟒蛇?更始终如一的会更好。
有什么想法吗?
发布于 2018-09-26 04:00:05
如果我没理解错你的问题,你就不能把字符串替换掉吗?with open(title, 'w') as f: f.write(res.replace("¥r¥n","¥n"))
发布于 2018-09-26 04:05:02
看看这个答案:
根据CSVReader的文档,默认情况下,它需要\r\n作为行分隔符。您的字符串应该可以与它很好地配合使用。如果将字符串加载到CSVReader对象中,则应该能够检查导出它的标准方法。
发布于 2018-09-26 07:26:30
Python字符串使用单个\n
换行符。通常,在读取文件时将\r\n
转换为\n
,并根据系统默认值和写入时的newline=
参数将换行符转换为\n
或\r\n
。
在您的例子中,当您从web界面读取\r
时,它并没有被删除。当您使用newline='\r\n'
打开文件时,python按照预期展开了\n
,但是\r
通过了,现在您的直线是\r\r\n
。您可以通过以二进制模式重新读取文本文件来查看这一点:
>>> res = 'foo,bar,stuff\r\n,more stuff,data,report\r\n,etc,etc,etc\r\n'
>>> open('test', 'w', newline='\r\n').write(res)
54
>>> open('test', 'rb').read()
b'foo,bar,stuff\r\r\n,more stuff,data,report\r\r\n,etc,etc,etc\r\r\n'
因为您已经有了想要的行尾,所以只需以二进制模式编写并跳过转换:
>>> open('test', 'wb').write(res.encode())
54
>>> open('test', 'rb').read()
b'foo,bar,stuff\r\n,more stuff,data,report\r\n,etc,etc,etc\r\n'
请注意,我使用的是系统默认编码,但您可能希望对编码进行标准化。
https://stackoverflow.com/questions/52505583
复制相似问题