您的位置:首页 > 编程语言 > Python开发

dblp 数据集之python lxml解析

2015-12-21 10:19 1706 查看
一:目的:解析出dblp.xml(1.7G)中2001年到2008年在www会议上发表文章的所有作者

二:python工具库 :lxml

三:lxml官方文档(最棒的参考资料):http://lxml.de/tutorial.html#elements-are-lists

四:xml解析的基础知识:

XML是一套定义语义标记的规则,这些标记将文档分成许多部件并对这些部件加以标识。 它也是元标记语言,即定义了用于定义其他与特定领域有关的、语义的、结构化的标记语言的句法语言。

五:xml解析方法:



1.SAX (simple API for XML )



2.DOM(Document Object Model)


3.ElementTree(元素树)

六:区别

DOM 易于学习和使用,因为它与基本 XML 文档紧密匹配。然而,对于大多数应用程序,处理 XML 文档只是其众多任务中的一种。例如,记帐软件包可能导入 XML 发票,但这不是其主要活动。计算帐户余额、跟踪支出以及使付款与发票匹配才是主要活动。记帐软件包可能已经具有一个数据结构(最有可能是数据库)。DOM 模型不太适合记帐应用程序,因为在那种情况下,应用程序必须在内存中维护数据的两份副本(一个是 DOM 树,另一个是应用程序自己的结构)。至少,在内存维护两次数据会使效率下降。对于桌面应用程序来说,这可能不是主要问题,但是它可能导致服务器瘫痪。对于不以
XML 为中心的应用程序,SAX 是明智的选择。实际上,SAX 并不在内存中显式地构建文档树。它使应用程序能用最有效率的方法存储数据。
七:使用SAX解析dblp的一个例子
提取出所有的作者信息 http://ju.outofmemory.cn/entry/137734 注:这个例子不能直接使用,因为我要的是:dblp->www->author中的数据.需要编写比较复杂的回调函数
八:主角lxml初介绍
一个简单详细的应用:http://www.cnblogs.com/bluescorpio/archive/2010/05/31/1748503.html
注:因为原始的dblp数据量比较大(1.7G),上面的方法不能直接使用,百般挫折,找到了下面的神器
九:lxml神器之iterparse
参考这个页面https://www.ibm.com/developerworks/cn/xml/x-hiperfparse/
还有这个http://4byte.cn/question/1677687/lxml-memory-usage-when-parsing-huge-xml-in-python.html
十:同道中人留下的部分中文文档 http://www.cnblogs.com/bluescorpio/archive/2010/05/31/1748503.html
最后留下解决最初问题的代码(欢迎大家赐教):

# coding=utf-8
'''
Created on Dec 19, 2015

@author: zxf
'''
from lxml import  etree
import codecs

counter = 0#所有的inproceedings数量
counter2 = 0#所有的满足条件的不同的作者数量
counter3=0#所有的满足条件的文章数量
nameSet = set()
# result = codecs.open("w2007.txt", 'w', 'utf-8')

for action, elem in etree.iterparse("dblp.xml", load_dtd=True):
flag = 0
#     print "%s element: %s" % (action, elem)
if elem.tag != "inproceedings" and elem.tag != "dblp" and elem.getparent().tag != "inproceedings":
elem.clear()
del elem
elif elem.tag == "inproceedings":
counter += 1

#VersionBest
year=[temp.text for temp in elem.iterchildren("year")][0]
booktitle=[temp.text for temp in elem.iterchildren("booktitle")][0]
if int(year) in range(2001,2009) and booktitle=="WWW":
counter3+=1
for author in [temp.text for temp in elem.iterchildren("author")]:
if author not in nameSet:
counter2+=1
print author
nameSet.add(author)

#VersionTwo
#         for elemTemp3 in elem.iterchildren("booktitle"):
#             if elemTemp3.text=="WWW":
#                 for elemTemp in elem.iterchildren("year"):
#                     if int(elemTemp.text) in range(2001,2009):
#                         counter3+=1
#                         for elemTemp in elem.iterchildren("title"):
#                             result.write(elemTemp.tag+" "+elemTemp.text+"  "+"\r\n")
#                         for elemTemp2 in elem.iterchildren("author"):
#                             if elemTemp2.text not in nameSet:
#                                 nameSet.add(elemTemp2.text)
#                                 print elemTemp2.tag,elemTemp2.text
#                                 counter2+=1
#versionOne
#         for elemTemp in elem.iterchildren("crossref"):
#             st = elemTemp.text.split("/")[1]
#             if st == "www":
#                 for elemTemp in elem.iterchildren("year"):
#                     if int(elemTemp.text) in range(2007, 2008):
#                         for elemTemp2 in elem.iterchildren("title"):
# #                             if elemTemp2.text not in nameSet:
# #                                 nameSet.add(elemTemp2.text)
# #                                 print elemTemp2.tag, elemTemp2.text
# #                                 counter2 += 1
#                             counter3+=1
#                             print elemTemp2.tag, elemTemp2.text
#                             result.write(elemTemp2.tag+" "+elemTemp2.text+"  "+"\r\n")
elem.clear()
del elem
# result.close()
print counter, counter2,counter3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: