Python 从MediaWiki XML提取页面标题和贡献者

Python 从MediaWiki XML提取页面标题和贡献者,python,xml-parsing,python-2.7,mediawiki,elementtree,Python,Xml Parsing,Python 2.7,Mediawiki,Elementtree,我有一个非常大(7GB)的MediaWiki XML转储,其中包含对Wiki的每个页面所做的每个更改的记录。我试图记录哪些用户对每个页面做出了贡献,因此我想从XML中提取这些信息 XML看起来像: <mediawiki xmlns="http://www.mediawiki.org/xml/export-0.3/"> <page> <title>Unique Page title</title> <id>11</id&g

我有一个非常大(7GB)的MediaWiki XML转储,其中包含对Wiki的每个页面所做的每个更改的记录。我试图记录哪些用户对每个页面做出了贡献,因此我想从XML中提取这些信息

XML看起来像:

<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.3/">
 <page>
  <title>Unique Page title</title>
  <id>11</id>
  <restrictions>sysop</restrictions>
  <revision>
    <id>11</id>
    <timestamp>2005-10-26T02:23:03Z</timestamp>
    <contributor>
      <ip>MediaWiki default</ip>
    </contributor>
    <text xml:space="preserve">i</text>
  </revision>
 </page>
 <page> ... </page>
 <page> ... </page>
 ...
</mediawiki>

尝试在迭代解析期间直接拉出“title”元素,而不是执行二次循环:

NS = '{http://www.mediawiki.org/xml/export-0.3/}'
from xml.etree.ElementTree import iterparse
with open('XMLFile.xml') as f:
    for event, elem in iterparse(f):
            if elem.tag == NS + 'title':
                print elem.text
            elem.clear()

似乎适合我。

我没有使用Python和iterparse的经验,但通常,使用迭代XML解析器执行此操作的方式如下:

  • 在解析循环之外,设置变量以存储当前页面标题和贡献者列表
  • 在循环内部,每当打开
    页面
    标记时,重置变量
  • 当遇到
    title
    标记时,将页面标题变量设置为其内容
  • 当遇到
    contributor
    标记时,将其内容添加到贡献者列表中
  • 页面
    标记关闭时,输出收集的标题和贡献者列表

打印
title
元素的文本内容时,您会得到
,因为您使用的是“太早”。默认情况下,仅生成“结束”事件。当发出
页面
的“结束”事件时,其所有子元素(包括
标题
)都已清除(清空)

如果问题代码中的
elem.clear()
仅向右移动一个缩进级别(四个空格),它将按预期工作。另一种使代码工作的方法是将
iterparse(f)
更改为
iterparse(f,events=[“start”])

node.text()
应该是
node.text

有关
iterparse()
的详细信息,请参阅


假设XML转储(mw.XML)如下所示:


唯一页面标题1
11
西索普
11
2005-10-26T02:23:03Z
爱丽丝
我
唯一页面标题2
11
西索普
11
2005-10-26T02:23:03Z
上下快速移动
J
以下是关于如何获得标题和投稿人的建议:

from xml.etree.ElementTree import iterparse

NS = '{http://www.mediawiki.org/xml/export-0.3/}'

with open('mw.xml') as f:
    for event, elem in iterparse(f):
        if elem.tag == '{0}page'.format(NS):
            title = elem.find("{0}title".format(NS))
            contr = elem.find(".//{0}username".format(NS))

            if title is not None:
                print title.text
            if contr is not None:
                print contr.text

            elem.clear()
输出:

Unique Page title 1 
Alice
Unique Page title 2 
Bob

我假设您需要贡献者的用户名。根据最新的,
contributor
可以包含
username
ip
、和/或
id
子元素(对于0.3版本的架构也是如此)。

我需要确保title元素和contributor都引用相同的修订版本,即,它们都具有相同的父元素。看起来这个解决方案不能做到这一点,对吗?应该会有帮助的。
Unique Page title 1 
Alice
Unique Page title 2 
Bob