2016-03-31 3 views
1

Я хочу прокрутить дамп Википедии в формате XML и для каждой ревизии хочу сохранить временную метку и комментарий, если ревизия производится определенным именем пользователя. Это возможно? Я пытаюсь ознакомиться с lxml.Извлечь данные из XML-файла, если аргументы имеют определенные значения.

<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.10/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.10/ http://www.mediawiki.org/xml/export-0.10.xsd" version="0.10" xml:lang="en"> 
    <siteinfo> 
     <sitename>Wikipedia</sitename> 
     <dbname>enwiki</dbname> 
     <base>https://en.wikipedia.org/wiki/Main_Page</base> 
     <generator>MediaWiki 1.27.0-wmf.18</generator> 
     <case>first-letter</case> 
     <namespaces>...</namespaces> 
    </siteinfo> 
    <page> 
     <title>Zhuangzi</title> 
     <ns>0</ns> 
     <id>42870472</id> 
     <revision> 
      <id>610251969</id> 
      <timestamp>2014-05-26T20:08:14Z</timestamp> 
      <contributor> 
       <username>White whirlwind</username> 
       <id>8761551</id> 
      </contributor> 
      <comment>...</comment> 
      <model>wikitext</model> 
      <format>text/x-wiki</format> 
      <text xml:space="preserve" bytes="41">#REDIRECT [[Zhuang Zhou]] {{R from move}}</text> 
      <sha1>9l31fcd4fp0cfxgearifr7jrs3240xl</sha1> 
     </revision> 
     <revision>...</revision> 
     <revision>...</revision> 
     <revision>...</revision> 
     <revision>...</revision> 
     <revision>...</revision> 

    </page> 
    <page>...</page> 
</mediawiki> 
+3

Какие инструменты вы нашли для чтения XML-данных и какого кода вы пытались использовать для выполнения своих задач? –

ответ

1
import xmltodict 


xml_input = """ 
<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.10/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.10/ http://www.mediawiki.org/xml/export-0.10.xsd" version="0.10" xml:lang="en"> 
<siteinfo> 
    <sitename>Wikipedia</sitename> 
    <dbname>enwiki</dbname> 
    <base>https://en.wikipedia.org/wiki/Main_Page</base> 
    <generator>MediaWiki 1.27.0-wmf.18</generator> 
    <case>first-letter</case> 
    <namespaces>...</namespaces> 
</siteinfo> 
<page> 
    <title>Zhuangzi</title> 
    <ns>0</ns> 
    <id>42870472</id> 
    <revision> 
     <id>610251969</id> 
     <timestamp>2014-05-25T20:08:14Z</timestamp> 
     <contributor> 
      <username>Patric</username> 
      <id>8761551</id> 
     </contributor> 
    </revision> 
    <revision> 
     <id>610251969</id> 
     <timestamp>2014-05-26T20:08:14Z</timestamp> 
     <contributor> 
      <username>Don</username> 
      <id>8761551</id> 
     </contributor> 
    </revision> 
    <revision> 
     <id>610251969</id> 
     <timestamp>2014-05-27T20:08:14Z</timestamp> 
     <contributor> 
      <username>Patric</username> 
      <id>8761551</id> 
     </contributor> 
    </revision>     
</page> 
</mediawiki> 
""" 


dic_xml = xmltodict.parse(xml_input) 

for rev in dic_xml['mediawiki']['page']['revision']: 
    if rev['contributor']['username'] == 'Patric': 
     print rev['id'] 
     print rev['timestamp'] 

с файлом:

import xmltodict 
with open('/home/jurkij/Downloads/testarticles.xml') as xml_file: 
    dic_xml = xmltodict.parse(xml_file.read()) 
    for page in dic_xml['mediawiki']['page']: 
     for rev in page['revision']: 
      if 'username' in rev['contributor'] and rev['contributor']['username'] == 'Aristophanes68': 
       print rev['timestamp'] 
       print rev['id'] 
+0

Выглядит хорошо, но я не могу заставить его работать с 'dic_xml = xmltodict.parse (open ('2articles.xml', encoding = 'latin-1'). Read())' – Knokkelgeddon

+0

Можете ли вы где-нибудь загрузить свой xml и вставить ссылку? – jurkij

+0

https://drive.google.com/file/d/0B3RwXj1XHe1fX0hDUEpmRENfUWs/view?usp=sharing – Knokkelgeddon

1

Да, это возможно с использованием lxml.

Вы знаете, какие узлы вы ищете (начните с имени пользователя reivision), поэтому напишите код, чтобы выбрать этот узел, и сравните значение с известным именем, которое вы ищете.

После того, как вы сделали эту часть, сохранение метки времени и комментариев должно быть простым.

Вы найдете то, что вам нужно в документации lxml (http://lxml.de/); загляните в разделы «XPath», чтобы выяснить, как выбрать нужные вам узлы (это будет включать фрагменты, которые загружают XML в ваш скрипт).

Возможно, вы также можете обратиться к учебнику ElementTree, что ссылки lxml (http://effbot.org/zone/element.htm) чтобы понять, как вы можете использовать XML-элементы, которые вы найдете, используя XPath или другие методы. Это будет полезно для получения значений из элементов.

1

Продвигаясь от вашего last question, вы можете легко сделать это с LXML и выражение XPath:

from lxml.etree import parse 

tree = parse("test.xml") 

ns = {"wiki": "http://www.mediawiki.org/xml/export-0.10/"} 
revs = tree.xpath("//wiki:revision[.//wiki:username='White whirlwind']",namespaces=ns) 

print([(rev.xpath(".//wiki:timestamp//text()", namespaces=ns)[0],rev.xpath(".//wiki:username//text()", namespaces=ns)[0]) for rev in revs]) 

Для следующего XML:

<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.10/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.10/ http://www.mediawiki.org/xml/export-0.10.xsd" version="0.10" xml:lang="en"> 
    <siteinfo> 
     <sitename>Wikipedia</sitename> 
     <dbname>enwiki</dbname> 
     <base>https://en.wikipedia.org/wiki/Main_Page</base> 
     <generator>MediaWiki 1.27.0-wmf.18</generator> 
     <case>first-letter</case> 
     <namespaces>...</namespaces> 
    </siteinfo> 
    <page> 
     <title>Zhuangzi</title> 
     <ns>0</ns> 
     <id>42870472</id> 
     <revision> 
      <id>610251969</id> 
      <timestamp>2014-05-26T20:08:14Z</timestamp> 
      <contributor> 
       <username>White whirlwind</username> 
       <id>8761551</id> 
      </contributor> 
      <comment>...</comment> 
      <model>wikitext</model> 
      <format>text/x-wiki</format> 
      <text xml:space="preserve" bytes="41">#REDIRECT [[Zhuang Zhou]] {{R from move}}</text> 
      <sha1>9l31fcd4fp0cfxgearifr7jrs3240xl</sha1> 
     </revision> 
     <revision> 
       <id>610251969</id> 
      <timestamp>2014-06-26T20:08:14Z</timestamp> 
      <contributor> 
       <username>White whirlwind</username> 
       <id>8761551</id> 
      </contributor> 
      <comment>...</comment> 
      <model>wikitext</model> 
      <format>text/x-wiki</format> 
      <text xml:space="preserve" bytes="41">#REDIRECT [[Zhuang Zhou]] {{R from move}}</text> 
      <sha1>9l31fcd4fp0cfxgearifr7jrs3240xl</sha1> 
     </revision> 
     <revision>  <id>610251969</id> 
      <timestamp>2014-07-26T20:08:14Z</timestamp> 
      <contributor> 
       <username>foobar</username> 
       <id>8761551</id> 
      </contributor> 
      <comment>...</comment> 
      <model>wikitext</model> 
      <format>text/x-wiki</format> 
      <text xml:space="preserve" bytes="41">#REDIRECT [[Zhuang Zhou]] {{R from move}}</text> 
      <sha1>9l31fcd4fp0cfxgearifr7jrs3240xl</sha1></revision> 
     <revision>...</revision> 
     <revision>...</revision> 
     <revision>...</revision> 

     </page> 

Выходы:

[[('2014-05-26T20:08:14Z', 'White whirlwind'), ('2014-06-26T20:08:14Z', 'White whirlwind')] 

//wiki:revision[.//wiki:username='White whirlwind'] находит все теги ревизий, которые содержат имя пользователя и что значение имени пользователя является White whirlwind, вы увидите, что она возвращает 2, как foo не совпадают, вам просто нужно извлечь значения метки времени и имени пользователя из каждой отфильтрованной ревизии в оборотах.

Для Вашего file in google drive возвращается:

[('2014-05-26T20:08:14Z', 'White whirlwind'), 
('2014-05-26T20:12:49Z', 'White whirlwind'), 
('2014-05-26T20:13:04Z', 'White whirlwind'), 
('2014-05-31T21:14:15Z', 'White whirlwind'), 
('2015-10-11T19:24:46Z', 'White whirlwind'), 
('2015-10-11T19:26:31Z', 'White whirlwind')] 

Что, если вы проверить файл правильно.