首页 文章

从MediaWiki XML中提取页面 Headers 和贡献者

提问于
浏览
3

我有一个非常大的(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 . 现在,我只是想打印 Headers ,但是当我运行以下代码时,它会打印出“无” .

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()

3 回答

  • 1

    尝试在迭代解析期间直接拉出'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()
    

    似乎对我有用 .

  • 1

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

    • 在解析循环之外,设置变量以存储当前页面 Headers 和贡献者列表 .

    • 在循环内部,每当打开 page 标记时,重置变量 .

    • 遇到 title 标记时,将页面 Headers 变量设置为其内容 .

    • 遇到 contributor 标记时,将其内容添加到贡献者列表中 .

    • page 标记关闭时,输出收集的 Headers 和贡献者列表 .

  • 3

    打印 title 元素的文本内容时会得到 None ,因为您使用的是elem.clear() "too early" . 默认情况下,iterparse()仅生成"end"事件 . 发出 page 的"end"事件时,其所有子元素(包括 title )都已清除(清空) .

    如果问题中的代码中的 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 Schemacontributor 可以包含 usernameip 和/或 id 子元素(对于0.3版本的模式也是如此) .

相关问题