在测试工作中,我们经常会遇到需要使用Python来读取XML、Excel、Json数据的场景,本篇文章把Python如何解析和处理这几种数据的做了一个归纳,方便实际使用时候的查询。
Python解析XML
大家都知道XML是一个标记语言,被设计用来传输和存储数据,日常工作中我们会遇到很多配置文件的格式是XML,也经常会遇到需要读取和修改XML文件的需求。
和Java一样,Python对于XML的解析也包括SAX和DOM,另外还有一个轻量级的ElementTree。这三个库都已经包含在了Python标准库里面。可以通过import xml.sax|dom 来导入相应的库。我们将会介绍SAX和DOM的优缺点,并以ElementTree为库来介绍Python对于XML文件的操作。
DOM(Document Object Model)的解析方式,会把整个XML文件在内存中解析成一个文件模型(一棵树),按照XMl中标签的层级关系来生成相应的节点,通过对树的操作来操作XML。这样操作的优点是通过树,可以比较简单的遍历和修改节点,适合对于做文件做修改操作。缺点是当XML文件比较大的时候,对于内存的开销有压力,解析的时间也会很长。
SAX(Simple API for XML)的解析方式,会逐行扫描文档,一边扫描一边进行解析。相比于DOM,SAX可以在解析过程中随时停止,是一种更快速的解析方法。也不会产生完整的结构对于内存有开销的压力,适合做对于XML的读取操作。
ElementTree我理解的是一个轻量级的DOM,提供了良好的API来方便我们遍历和修改XML节点。
引用方法
ElementTree库保存在Lib/xml/etree/ElementTree.py文件下面,可以用以下的语句来进行导入.(以Python3为例)
import xml.etree.ElementTree as ET
XML文件格式和内容
本段用到的XML文件sample.xml内容如下
<?xml version="1.0"?>
1
2008
141100
4
2011
59900
68
2011
13600
解析XML
读入文件
首先,我们需要读入XML.
tree = ET.parse('sample.xml')
root = tree.getroot()
如果不是需要读入的XML不是文件还是一个字符串,我们可以用一下的方式读取
root=ET.fromstring(sample_string)
parse()方法读取XML文件,返回的是XML的解析树,类型是ElementTree
ElementTree包含以下常用方法:
find(match) # 查找第一个匹配的子元素, match可以时tag或是xpaht路径
findall(match) # 返回所有匹配的子元素列表
findtext(match, default=None) # 返回第一项匹配text值的元素
iter(tag=None) # 以当前元素为根节点 创建树迭代器,如果tag不为None,则以tag进行过滤
iterfind(match) # 通过tag和path查找所有匹配的子元素列表
fromstring()方法读取的是字符串,返回解析树的root节点,类型是Element
Element包含一下常用属性和方法:
attrib #为包含元素属性的字典
keys() #返回元素属性名称列表
items() #返回(name,value)列表
get(key, default=None) #获取属性
set(key, value) # 更新/添加 属性
del xxx.attrib[key] # 删除对应的属性
完整的API可以查看以下文档
https://docs.python.org/3/library/xml.etree.elementtree.html?
下面介绍一些常用方法的使用
查看
可以通过简单的循环来遍历每个节点,并可以进行嵌套。
for child in root
print(child.tag,":", child.attrib)
另外,因为有层级关系,所以可以通过下标的方式直接访问各个节点。
print(root[0].tag) #country
print(root[0][0].tag) #rank
下标访问的方法虽然简单,但是在未知XML具体结构的时候并不适用,通过Tag名称访问的方法更具有普适性。
for neighbor in root.iter('year'):
print(neighbor.text)
Element.findall()只查找直接的孩子,返回所有符合要求的Tag的Element,而Element.find()只返回符合要求的第一个Element。
修改
前面已经介绍了如何获取一个Element的对象,以及查看它的Tag、Attribute、值和它的孩子。下面介绍如何修改一个Element并对XML文件进行保存
下面的Element请替换成实际相应的变量
修改Element
Element.set('AttributeName','AttributeValue')
Elemnt.text="new text"
添加Element
Element.append(childElement)
删除Element
Element.remove(childElement)
Python解析Excel
通常比较简单的Excel的读写的话,可以用xlwt来进行写,xlrd来进行读。
如果运用Python来进行数据分析,一般需要结合pandas和numpy来进行数据的处理,pandas也结合了对于Excel的处理。
xlwt和xlrd读写Excel
xlwt和xlrd用起来都比较简单,下面的例子是通过xlrd和xlwt处理的两个实例。
读取Excel import xlrd
workbook = xlrd.open_workbook(u'sample.xls') //打开Excel文件
sheet_names= workbook.sheet_names() //获取Excel文件中每个Sheet的名字,返回一个list
for sheet_name in sheet_names: //遍历
sheet2 = workbook.sheet_by_name(sheet_name)//通过名字获取sheet
// sheet2 = workbook.sheet_by_index(1) //通过索引获取sheet
print sheet_name rows = sheet2.row_values(3) # 获取第四行内容
cols = sheet2.col_values(1) # 获取第二列内容
print rows
print cols
写入Excel import xlwt
wbk = xlwt.Workbook()
sheet = wbk.add_sheet('sheet 1') //新建一个Sheet
sheet.write(0,1,'test text')#第0行第一列写入内容
sheet.write_merge(1,1,2,3,"test")//在第2行横向合并第3,4列
sheet.write_merge(2,3,3,3,"test")//在第3,4行纵向合并第4列
wbk.save('test.xls')
另外,在读取Excel的时候,会根据字段的类型不同往往会遇到不通的问题。
** 读取内容为日期的格式**
Python读取Excel时会返回5中类型,可以通过ctype来查看。这5种类型是:
0 empty,1 string,2 number, 3 date,4 boolean,5 error
如果我们不加判断的话可能会遇到读取为空的问题。 可以通过xldate_as_tuple来处理为date格式。
from datetime import date,datetime
print(sheet1.cell(1,2).ctype)
date_value = xlrd.xldate_as_tuple(sheet1.cell_value(1,2),wb.datemode)
print(date(*date_value[:3]))
print(date(*date_value[:3]).strftime('%Y/%m/%d'))
获取合并的单元格内容
主要会通过merged_cells(row, row_range, col, col_range)这个方法来合并单元格,其中[row, row_range),[col, col_range)都是左开右闭。
导入pandas
import pandas as pd
Python解析Json
TODO