Jestem nowy do parsowania XML i Pythona, więc niedźwiedź ze mną. Używam LXML do analizowania zrzutu wiki, ale chcę tylko na każdą stronę, jego tytuł i tekst.

Na razie mam to:

from xml.etree import ElementTree as etree

def parser(file_name):
    document = etree.parse(file_name)
    titles = document.findall('.//title')
    print titles

W tej chwili tytuły nic nie zwracają. Spojrzałem na poprzednie odpowiedzi, takie jak ten: ElementRee Findall () Powrót Pusta lista oraz dokumentacja LXML, ale większość rzeczy wydawała się dostosowana do analizowania HTML.

Jest to sekcja mojego XML:

<mediawiki xmlns="http://www.mediawiki.org/xml/export-0.7/"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.7/ http://www.mediawiki.org/xml/export-0.7.xsd" version="0.7" xml:lang="en">
  <siteinfo>
  <sitename>Wikipedia</sitename>
<base>http://en.wikipedia.org/wiki/Main_Page</base>
<generator>MediaWiki 1.20wmf9</generator>
<case>first-letter</case>
<namespaces>
  <namespace key="-2" case="first-letter">Media</namespace>
  <namespace key="-1" case="first-letter">Special</namespace>
  <namespace key="0" case="first-letter" />
  <namespace key="1" case="first-letter">Talk</namespace>
  <namespace key="2" case="first-letter">User</namespace>
  <namespace key="3" case="first-letter">User talk</namespace>
  <namespace key="4" case="first-letter">Wikipedia</namespace>
  <namespace key="5" case="first-letter">Wikipedia talk</namespace>
  <namespace key="6" case="first-letter">File</namespace>
  <namespace key="7" case="first-letter">File talk</namespace>
  <namespace key="8" case="first-letter">MediaWiki</namespace>
  <namespace key="9" case="first-letter">MediaWiki talk</namespace>
  <namespace key="10" case="first-letter">Template</namespace>
  <namespace key="11" case="first-letter">Template talk</namespace>
  <namespace key="12" case="first-letter">Help</namespace>
  <namespace key="13" case="first-letter">Help talk</namespace>
  <namespace key="14" case="first-letter">Category</namespace>
  <namespace key="15" case="first-letter">Category talk</namespace>
  <namespace key="100" case="first-letter">Portal</namespace>
  <namespace key="101" case="first-letter">Portal talk</namespace>
  <namespace key="108" case="first-letter">Book</namespace>
  <namespace key="109" case="first-letter">Book talk</namespace>
</namespaces>
  </siteinfo>
  <page>
    <title>Aratrum</title>
    <ns>0</ns>
    <id>65741</id>
    <revision>
  <id>349931990</id>
  <parentid>225434394</parentid>
  <timestamp>2010-03-15T02:55:02Z</timestamp>
  <contributor>
    <ip>143.105.193.119</ip>
  </contributor>
  <comment>/* Sources */</comment>
  <sha1>2zkdnl9nsd1fbopv0fpwu2j5gdf0haw</sha1>
  <text xml:space="preserve" bytes="1436">'''Aratrum''' is the Latin word for  [[plough]], and &quot;arotron&quot; (αροτρον) is the [[Greek language|Greek]] word. The   [[Ancient Greece|Greeks]] appear to have had diverse kinds of plough from the earliest  historical records. [[Hesiod]] advised the farmer to have always two ploughs, so that if  one broke the other might be ready for use. These ploughs should be of two kinds, the one  called &quot;autoguos&quot; (αυτογυος, &quot;self-limbed&quot;), in which the plough-tail  was of the same piece of timber as the share-beam and the pole; and the other called  &quot;pekton&quot; (πηκτον, &quot;fixed&quot;), because in it, three parts, which were of  three kinds of timber, were adjusted to one another, and fastened together by nails.

The ''autoguos'' plough was made from a [[sapling]] with two branches growing from its   trunk in opposite directions. In ploughing, the trunk served as the pole, one of the two     branches stood upwards and became the tail, and the other penetrated the ground and,    sometimes shod with bronze or iron, acted as the [[ploughshare]]. 

==Sources==
Based on an article from ''A Dictionary of Greek and Roman Antiquities,'' John Murray,     London, 1875.
ἄρατρον

==External links==
*[http://penelope.uchicago.edu/Thayer/E/Roman/Texts/secondary/SMIGRA*/Aratrum.html Smith's     Dictionary article], with diagrams, further details, sources.
[[Category:Agricultural machinery]]
[[Category:Ancient Greece]]
[[Category:Animal equipment]]</text>
</revision>
</page>

Próbowałem też ierparatse, a następnie drukować znacznik elementu, które znajdzie:

for e in etree.iterparse(file_name):
    print e.tag

Ale narzeka na adres E, który nie ma atrybutu znacznika.

EDYTOWAĆ: Screenshot

15
liloka 7 grudzień 2013, 03:36

2 odpowiedzi

Najlepsza odpowiedź

Problem polega na tym, że nie bierzesz pod uwagę przestrzeni nazw XML. Dokument XML (i wszystkie elementy w IT) znajduje się w przestrzeni nazw http://www.mediawiki.org/xml/export-0.7/. Aby to działać, musisz się zmienić

titles = document.findall('.//title')

Do

titles = document.findall('.//{http://www.mediawiki.org/xml/export-0.7/}title')

Przestrzeń przestrzeni nazw może być również zapewniona za pomocą parametru namespaces:

NSMAP = {'mw':'http://www.mediawiki.org/xml/export-0.7/'}
titles = document.findall('.//mw:title', namespaces=NSMAP)

Działa to w Pythonie 2.7, ale nie jest wyjaśnione w Dokumentacja Python 2.7 (Python 3.3 Dokumentacja jest lepsza).

Zobacz także http://effbot.org/zone/zone/plomespace.htm i to Więc pytanie z odpowiedzią: Parsowanie XML z przestrzeni nazw w Pythonie przez "ElementTree".


Problem z iterparse() jest spowodowany faktem, że ta funkcja zapewnia (event, element) Tules (nie tylko elementy). Aby uzyskać nazwę tagów, zmień

for e in etree.iterparse(file_name):
    print e.tag

Do tego:

for e in etree.iterparse(file_name):
    print e[1].tag
28
Community 23 maj 2017, 10:31

Po pierwsze, musisz zlokalizować element macierzystego, page. Nie wiem, ile warstw jest zagnieżdżone, ale po tym, że go znajdziesz, możesz natychmiast uzyskać znacznik title:

>>> page_tag = ET.fromstring(xdata)
>>> title_tag = page_tag.find('title')
>>> title_tag.text
'Aratrum'

Z więcej informacji zalanymi, możesz to zrobić:

def parser(file_name):
    document = etree.parse(file_name)
    titles = []
    for page_tag in document.findall('page'):
        titles.append(page_tag.find('title').text)
    return titles

Mam nadzieję że to pomoże!

0
aIKid 7 grudzień 2013, 15:51