Python 流解析Wiki Xml转储
我不确定以前是否有人问过这个问题,但我一直找不到,请原谅我的无知。我想解析(流解析)大约40 Gig的WikipediaXML转储。我正试图使用lxml iterparse aka stream parser为我完成这项工作,但由于某些原因,我编写的代码对我来说不起作用。在我解释我想做什么之前,让我们考虑一下这个XML格式Python 流解析Wiki Xml转储,python,xml-parsing,lxml,wikipedia,topic-modeling,Python,Xml Parsing,Lxml,Wikipedia,Topic Modeling,我不确定以前是否有人问过这个问题,但我一直找不到,请原谅我的无知。我想解析(流解析)大约40 Gig的WikipediaXML转储。我正试图使用lxml iterparse aka stream parser为我完成这项工作,但由于某些原因,我编写的代码对我来说不起作用。在我解释我想做什么之前,让我们考虑一下这个XML格式 <root> <page> <title> A </title> <text> ......
<root>
<page>
<title> A </title>
<text> ..........blah blah...... </text>
</page>
<page>
<title> B </title>
<text> This is a line of sample text in title B </text>
</page>
<page>
<title> C </title>
<text> ............blah blah........ </text>
</page>
</root>
请随意完全修改代码并给出您自己的版本,只要我能解决问题,我真的不会介意
谁来帮忙 从xml.sax导入ContentHandler,parseString
from xml.sax import ContentHandler, parseString
from StringIO import StringIO
from lxml import etree
CONTENT = """
<root>
<page>
<title> A </title>
<text> ..........blah blah...... </text>
</page>
<page>
<title> B </title>
<text> This is a line of sample text in title B </text>
</page>
<page>
<title> C </title>
<text> ............blah blah........ </text>
</page>
</root>
"""
def fast_iter(context, func):
for action, elem in context:
func(elem)
elem.clear()
while elem.getprevious() is not None:
del elem.getparent()[0]
del context
def process_element(elem):
print elem.xpath( './text/text( )' )
class WikiContentHandler(ContentHandler):
def startDocument(self):
self.character_buffer = None
def startElement(self, name, attrs):
if name == 'text':
self.character_buffer = StringIO()
def endElement(self, name):
if name == 'text':
print self.character_buffer.getvalue()
self.character_buffer.close()
self.character_buffer = None
def characters(self, content):
if self.character_buffer != None:
self.character_buffer.write(content)
def parse_wiki():
parseString(CONTENT, WikiContentHandler())
if __name__ == '__main__':
parse_wiki()
context = etree.iterparse( StringIO(CONTENT), tag='page' )
fast_iter(context, process_element)
从StringIO导入StringIO
从lxml导入etree
CONTENT=”“”
A.
诸如此类。。。。。。
B
这是标题B中的一行示例文本
C
诸如此类。。。。。。。。
"""
def fast_iter(上下文,函数):
对于行动,上下文中的元素:
func(elem)
元素清除()
虽然elem.getprevious()不是无:
del elem.getparent()[0]
删除上下文
def过程要素(要素):
打印元素xpath('./text/text()'))
类WikiContentHandler(ContentHandler):
def startDocument(自我):
self.character\u buffer=None
def startElement(自身、名称、属性):
如果名称=='text':
self.character\u buffer=StringIO()
定义元素(自身、名称):
如果名称=='text':
打印self.character\u buffer.getvalue()
self.character\u buffer.close()
self.character\u buffer=None
def字符(自身、内容):
如果self.character\u缓冲区!=无:
self.character\u buffer.write(内容)
def parse_wiki():
parseString(内容,WikiContentHandler())
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
parse_wiki()
context=etree.iterparse(StringIO(CONTENT),tag='page')
fast\u iter(上下文、过程元素)
以上是两种解析XML的方法,一种使用lxml,另一种使用Python标准库。它们都打印出
标记中的所有信息。只需查看打印语句的位置并进行额外处理。您能缩小问题范围吗?谢谢您的快速评论。您能帮我解析xml(以示例结构为例)并打印出文件中标记内的所有内容吗?我只需要一个适用于此xml结构的示例代码。我不是python专家,所以这里也有一点问题。对不起,你的代码怎么会失败?它是干什么的?这一点都不清楚。哪个是哪个?您已经声明了内容,但似乎没有在任何地方使用它;在这两个示例中,parseString()中使用了.CONTENT,它使用python附带的SAX解析器。另一个解析器是etree.iterparse(StringIO(CONTENT),tag='page'),它使用lxml。您需要向下滚动代码以查看内容的使用位置。
from xml.sax import ContentHandler, parseString
from StringIO import StringIO
from lxml import etree
CONTENT = """
<root>
<page>
<title> A </title>
<text> ..........blah blah...... </text>
</page>
<page>
<title> B </title>
<text> This is a line of sample text in title B </text>
</page>
<page>
<title> C </title>
<text> ............blah blah........ </text>
</page>
</root>
"""
def fast_iter(context, func):
for action, elem in context:
func(elem)
elem.clear()
while elem.getprevious() is not None:
del elem.getparent()[0]
del context
def process_element(elem):
print elem.xpath( './text/text( )' )
class WikiContentHandler(ContentHandler):
def startDocument(self):
self.character_buffer = None
def startElement(self, name, attrs):
if name == 'text':
self.character_buffer = StringIO()
def endElement(self, name):
if name == 'text':
print self.character_buffer.getvalue()
self.character_buffer.close()
self.character_buffer = None
def characters(self, content):
if self.character_buffer != None:
self.character_buffer.write(content)
def parse_wiki():
parseString(CONTENT, WikiContentHandler())
if __name__ == '__main__':
parse_wiki()
context = etree.iterparse( StringIO(CONTENT), tag='page' )
fast_iter(context, process_element)