CSV文件解析
一、CSV概念
1、逗号分隔值(Comma-Separated Values,CSV),其文件以纯文本形式存储表格数据(数字和文本),文件的每一行都是一个数据记录。每个记录由一个或多个字段组成,用逗号分隔。使用逗号作为字段分隔符是此文件格式的名称的来源,因为分隔字符也可以不是逗号,有时也称为字符分隔值。
2、CSV广泛用于不同体系结构的应用程序之间交换数据表格信息,解决不兼容数据格式的互通问题,一般按照传输双方既定标准进行格式定义,而其本身并无明确格式标准。
3、CSV用逗号分隔字段的基本思想是清楚的,但是当字段数据也可能包含逗号或者甚至嵌入换行符时,该想法变得复杂。 CSV实现可能无法处理这些字段数据,或者可能会使用引号来包围字段。引用并不能解决所有问题:有些字段可能需要嵌入引号,因此CSV实现可能包含转义字符或转义序列。
二、CSV的格式规范
具体文件格式:
1.每条记录占一行 以逗号为分隔符
2.逗号前后的空格会被忽略
3.字段中包含有逗号,该字段必须用双引号括起来
4.字段中包含有换行符,该字段必须用双引号括起来
5.字段前后包含有空格,该字段必须用双引号括起来
6.字段中的双引号用两个双引号表示
7.字段中如果有双引号,该字段必须用双引号括起来
8.第一条记录,可以是字段名
下面的格式规范定义来源于RFC 4180:
1. 每一行记录位于一个单独的行上,用回车换行符CRLF(也就是\r\n)分割。
1 aaa,bbb,ccc CRLF 2 zzz,yyy,xxx CRLF
2. 文件中的最后一行记录可以有结尾回车换行符,也可以没有。
1 aaa,bbb,ccc CRLF 2 zzz,yyy,xxx
3.第一行可以存在一个可选的标题头,格式和普通记录行的格式一样。标题头要包含文件记录字段对应的名称,应该有和记录字段一样的数量。(在MIME类型中,标题头行的存在与否可以通过MIME type中的可选”header”参数指明)
1 field_name,field_name,field_name CRLF 2 aaa,bbb,ccc CRLF 3 zzz,yyy,xxx CRLF
4. 在标题头行和普通行每行记录中,会存在一个或多个由半角逗号(,)分隔的字段。整个文件中每行应包含相同数量的字段,空格也是字段的一部分,不应被忽略。每一行记录最后一个字段后不能跟逗号。(通常用逗号分隔,也有其他字符分隔的CSV,需事先约定)
1 aaa,bbb,ccc
5. 每个字段可用也可不用半角双引号(“)括起来(不过有些程序,如Microsoft的Excel就根本不用双引号)。如果字段没有用引号括起来,那么该字段内部不能出现双引号字符。
1 "aaa","bbb","ccc" CRLF 2 zzz,yyy,xxx
6. 字段中若包含回车换行符、双引号或者逗号,该字段需要用双引号括起来。
1 "aaa","b CRLF 2 bb","ccc" CRLF 3 zzz,yyy,xxx
7. 如果用双引号括字段,那么出现在字段内的双引号前必须加一个双引号进行转义。
1 "aaa","b""bb","ccc"
三、CSV文件解析
CSV并不是一种单一的、定义明确的格式,因此在实践中,术语“CSV”泛指具有以下特征的任何文件:
- 纯文本,使用某个字符集,比如ASCII、Unicode、EBCDIC或GB2312;
- 由记录组成(典型的是每行一条记录);
- 每条记录被分隔符分隔为字段(典型分隔符有逗号、分号或制表符;有时分隔符可以包括可选的空格);
- 每条记录都有同样的字段序列。
Python读取CSV文件的三种方式:
普通方法读取:
with open("fileName.csv") as file: for line in file: print line
用CSV标准库读取:
import csv csv_reader = csv.reader(open("fileName.csv")) for row in csv_reader: print row
用pandas读取:
import pandas as pd data = pd.read_csv("fileName.csv") print data data = pd.read_table("fileName.csv",sep=",") print data
CSV文件存储
前言
CSV,全称为Comma-Separated Values,中文名可以叫做字符分隔值或逗号分隔值,以纯文本形式存储表格数据,文本默认以逗号分隔,CSV相当于一个结构化表的纯文本形式,比Excel文件更加简洁,保存数据非常方便。
单行写入
import csv with open('demo.csv', 'w', encoding='utf-8') as csvf: writer = csv.writer(csvf) writer.writerow(['id', 'name', 'gender']) writer.writerow(['100', 'makerchen', 'male']) writer.writerow(['101', 'makerliu', 'female']) writer.writerow(['102', 'makerqin', 'male'])
首先调用csv库的 writer() 方法初始化写入对象,然后再调用 writerow() 方法传入每行的数据即可完成写入。且默认行数据之间以逗号分隔【csv文件一般都是按照行数据写入】
运行结果:
如果想修改列与列之间的分隔符,可以传入参数 delimiter ,代码如下:
import csv with open('demo.csv', 'w', encoding='utf-8') as csvf: writer = csv.writer(csvf, delimiter=' ') writer.writerow(['id', 'name', 'gender']) writer.writerow(['100', 'makerchen', 'male']) writer.writerow(['101', 'makerliu', 'female']) writer.writerow(['102', 'makerqin', 'male'])
这里表示每一列数据以空格分隔。
运行结果:
多行写入
调用 writerows() 方法就可以同时写入多行,此时参数需要为二维列表。代码如下:
import csv with open('demo.csv', 'w', encoding='utf-8') as csvf: writer = csv.writer(csvf) writer.writerow(['id', 'name', 'gender']) writer.writerows([['100', 'makerchen', 'male'], # 传参为可迭代的数据类型 ['101', 'makerliu', 'female'], ['102', 'makerqin', 'male']])
运行结果:
字典写入
一般情况下,爬虫提取的数据都是结构化数据,我们一般会用字典来表示,代码如下:
import csv with open('demo.csv','w',encoding='utf-8') as csvf: fieldnames = ['id','name','gender'] writer = csv.DictWriter(csvf,fieldnames=fieldnames) writer.writeheader() writer.writerow({'id':'100','name':'makerchen','gender':'male'}) writer.writerow({'id':'101','name':'makerliu','gender':'female'}) writer.writerow({'id':'102','name':'makerqin','gender':'male'})
运行结果:
首先用 fieldnames 定义头信息,然后将其传给 DictWriter 来初始化一个字典写入对象,接着用 writeheader() 方法写入头信息,最后调用 writerow() 方法传入字典即可。
如果想追加写入的话,可将 open() 方法的第二个参数改为a,代码如下:
with open('demo.csv','a',encoding='utf-8') as csvf
读取CSV文件
将刚才写入的文件内容读取出来,代码如下:
import csv with open('demo.csv','r',encoding='utf-8') as csvf: datas = csv.reader(csvf) for data in datas: print(data)
运行结果:
通过遍历输出每行内容,每一行都是一个列表形式。
【注意】如果CSV文件中包含中文的话,还需要指定文件编码。
当然也可以用pandas库中的 read_csv() 方法将数据从CSV中读取出来:
import pandas as pd data = pd.read_csv('demo.csv') print(data)
此种方式在做数据分析的时候用的比较多,也是一种比较方便读取CVS文件的方法。