Stream Parse Wiki Xml转储

时间:2012-12-03 05:35:46

标签: python xml-parsing lxml wikipedia topic-modeling

我不确定此问题是否曾被问过,但我一直找不到它,请原谅我的无知。我想解析(流解析)大约40 Gigs的维基百科xml转储。我正在尝试使用lxml iterparse aka流解析器为我做这个工作,但我写的代码由于某种原因不适合我。在我解释我想要做什么之前,让我们考虑一下这个xml格式

<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结构中,这是wiki转储的重要内容,我想要做的是使用python流解析器读取“page”标签内的每个内容(基本上将转储中的不同文章分开)作为lxml(不将整个xml树加载到内存中是不可能的)并在其上执行正则表达式。确切地说,我想要做的是,如果在当前“page”元素中查找文本标签“Category:Living People”内部,如果找到这样的匹配正则表达式,则将“text”标签内的整个内容写出为文本文件。但在正则表达式部分之前,我遇到了lxml解析器本身的问题。我在下面尝试的示例代码。在此先感谢:)

#LXML parser
from lxml import etree

def fast_iter(context, func):
    for event, 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( 'description/text( )' )

context = etree.iterparse( MYFILE, tag='item' )
fast_iter(context,process_element)

随意完全改变代码并提供您自己的版本,只要我将问题排序,我真的不介意!

有人请帮助!

1 个答案:

答案 0 :(得分:0)

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)

以上是两种解析XML的方法,一种使用lxml,另一种使用Python标准库。它们都打印出<text>标签中的所有信息。只需查看打印报表的位置并进行额外处理。