Python csv.writer写入异常:分隔符失效、输出带括号如何解决
爬取网页得到两个字段内容:
- title:
A title - Description:
A description with, a comma.
使用如下CSV写入代码时输出不符合预期:
rows = title, desc with open('\scrape.csv', 'a', encoding='UTF8', newline='') as f: writer = csv.writer(f, delimiter='|', quoting=csv.QUOTE_NONE, escapechar='\\') writer.writerow([rows])
预期写入结果:
A title | A description with, a comma.
实际输出结果:('A title', \"A description with, a comma.\")
对应三点疑问:
- 为什么设置的
|分隔符没有生效? - 为什么输出内容被括号包裹?
- 是否可以移除代码中配置的
escapechar='\\'参数?
1. |分隔符不生效的原因
csv.writer的分隔符只会插入在同一行的不同列之间。代码里rows = title, desc本身已经是一个包含两个元素的元组,之后调用writer.writerow([rows])时,相当于给writerow传了一个只包含1个元素的列表——这个唯一元素就是之前构造的二元组。整行只有1列,自然没有位置插入列分隔符|。
2. 输出带括号的原因
writerow写入非字符串类型的内容时,会自动调用str()将内容转为字符串。传入的唯一列内容是元组类型,Python对元组做字符串转换时,默认输出格式就是用小括号包裹所有元素、元素间用逗号分隔,也就是('A title', 'A description with, a comma.')的形式。再加上设置了quoting=csv.QUOTE_NONE不给字段加引号,描述内容里的逗号属于CSV特殊字符,会被自动加上配置的\转义符,最终就得到了实际看到的输出。
3. 能否移除escapechar='\\'参数
不能直接移除。当设置quoting=csv.QUOTE_NONE时,所有字段都不会被引号包裹,此时如果字段内容中出现分隔符、换行符这类CSV语法特殊字符,必须通过转义符标记该字符属于内容本身、不是语法分隔符。如果直接删除escapechar参数,遇到包含特殊字符的字段时csv模块会直接抛出错误。
如果不想使用转义符,可以将quoting参数改为csv.QUOTE_MINIMAL,此时只有包含特殊字符的字段会被自动包裹引号,不需要额外转义就能正确解析。
import csv title = "A title" desc = "A description with, a comma." # 直接构造列列表,不要嵌套 rows = [title, desc] with open('scrape.csv', 'a', encoding='UTF8', newline='') as f: writer = csv.writer(f, delimiter='|', quoting=csv.QUOTE_MINIMAL) writer.writerow(rows)
运行上述代码后,文件写入结果和预期完全一致。
内容的提问来源于stack exchange,提问作者Markus Ham

