我有一个非常大的(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>
对于这个大小的文件,我相信我需要使用iterparse.现在,我只是想打印标题,但是当我运行以下代码时,它会打印“无”.
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 + 'page':
for node in elem:
if node.tag == NS + 'title':
print node.text()
elem.clear()
解决方法:
打印标题元素的文本内容时,您将获得无,因为您使用elem.clear()
“太早”.默认情况下,iterparse()
仅生成“结束”事件.当发出页面的“结束”事件时,其所有子元素(包括标题)都已被清除(清空).
如果问题代码中的elem.clear()只向右移动了一个缩进级别(四个空格),它将按预期工作.使代码工作的另一种方法是将iterparse(f)更改为iterparse(f,events = [“start”]).
node.text()应该是node.text.
有关iterparse()的更多详细信息,请参见http://effbot.org/zone/element-iterparse.htm.
假设XML转储(mw.xml)如下所示:
<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.3/">
<page>
<title>Unique Page title 1</title>
<id>11</id>
<restrictions>sysop</restrictions>
<revision>
<id>11</id>
<timestamp>2005-10-26T02:23:03Z</timestamp>
<contributor>
<username>Alice</username>
</contributor>
<text xml:space="preserve">i</text>
</revision>
</page>
<page>
<title>Unique Page title 2</title>
<id>11</id>
<restrictions>sysop</restrictions>
<revision>
<id>11</id>
<timestamp>2005-10-26T02:23:03Z</timestamp>
<contributor>
<username>Bob</username>
</contributor>
<text xml:space="preserve">j</text>
</revision>
</page>
</mediawiki>
以下是关于如何获得头衔和贡献者的建议:
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
我假设你想要贡献者的用户名.根据最新的XML Schema,贡献者可以包含username,ip和/或id子元素(对于0.3版本的模式也是如此).