注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

江志祥的博客

可恶的中国银行,信用卡像病毒啊,取消那么难,,,

 
 
 

日志

 
 

用lxml来解析大型xml文件+命令行中的python  

2011-09-07 23:30:30|  分类: 计算机-Python |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

上周被布置了一个任务,要解析一个大约有600MB左右的xml文件,从中提取所需的信息然后输出成一个csv文件。从来没有做过类似东西 的我,加上不太熟悉的python、linux和vim,这样一个简单的东西花了一天半才解决,不过解决的还算比较完美吧,用lxml这个库,原本以为要 至少10几分钟的解析过程其实只用了1分钟左右,说起来,还是c比较强大啊,lxml的底层使用c实现的,换成python恐怕就够呛了。好了废话不多 说,讲讲lxml的用法和我在做这个任务里碰到的几个问题吧,权当复习和备份。

用lxml载入xml文件

lxml是c中的libxml的python实现,在保证效率的情况下,为程序员免去了内存管理方面的麻烦,具体介绍大家还是移步它的官网吧。

首先在python里import lxml的etree模块,然后用etree里的parse函数从文件中解析xml,解析得到的是一个ElementTree的实例,用这个实例的 getroot函数就能得到xml中的root。root是对象Element的一个实例,对这个root可以做indexing,即用过root[n] 可以得到root下相应的子节点,这些子节点同样也是Element的实例,所以通过root[n][m]就可遍历各个节点。

>>>from lxml import etree

>>>tree = etree.parse(open(“file_name”,“rb”))

>>>root = tree.getroot()

另外,对一个Element还可以进行iterate操作,iterate会依次遍历Element下的所有子节点、子节点的子节点,然后按照顺序,返回一个所有节点的序列。

如果我们有这样一个xml:

<root>

<child>

<grandson1/>

<grandson2>name1</grandson2>

</child>

<child>

<grandson1/>

<grandson2>name2</grandson2>

</child>

</root>

那么:

>>>root[0]    #返回第一个child节点的Element实例

>>>root[0][0]    #返回第一个child中grandson1

>>>root.iter()    #按顺序返回root中所有节点

那么如何得到各个节点中的信息呢?其实也很方便,用element.text、element.tag可以得到节点的内容和节点的名字。另外用element.get(“attribute_name”)还可以得到节点中attribute的值。

如:

>>>for child in root:

>>>    for son in child.iter():

>>>        print son.tag, “:”, son.text

这样一段代码就可以遍历每个上面那个xml中每一个child中的grandchild的名字了。

另外,lxml还提供了丰富的写xml的功能,和读写html的功能,可以说是一场强大,有兴趣的童鞋可以自行研究~

像运行*nix命令一样用python模块

我做的这个解析功能是给同事用的,所以自己加了点代码好让同事在命令行中利用这个代码。

我想实现的功能是,当同事在bash中运行:

$:python parser.py –f some_xml_file.xml

便可以直接跑我的代码来解析xml了。当同事运行:

$:python parser.py

的时候,会把这个模块的用法打印出来。具体代码如下,各个行的作用我用注释标注了:

if __name__ == “__main__”:

#引用OptionParse模块:
from optparse import OptionParser

#初始化一个Parser,这时可以用usage参数写下模块说明:
parser = OptionParser(usage=”%prog [options] xml_filename\n”
“available option:   -f    indicates the xml file name”)

#添加一个option,缩写为-f,全称是–file:
parser.add_option(‘-f’, ‘–file’)

#从命令行中得到option和arguments:
options, args = parser.parse_args()

#如果file不为空,则运行模块:
if options.file:
sys.exit(parse_feed(options.file))

#若file是空,则打印出模块用法:
else:
parser.print_usage()
sys.exit(1)

这样,一个可以让人方便使用的模块就写好了。

  评论这张
 
阅读(2129)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018