Frage

Angenommen, ich habe diese Art von HTML, von dem ich brauche, um „text2“ mit lxml / ElementTree:

<div>text1<span>childtext1</span>text2<span>childtext2</span>text3</div>

Wenn ich schon das div-Element als mydiv haben, dann mydiv.text kehrt nur "text1".

Mit itertext () scheint problematisch oder umständlich bestenfalls, da sie den gesamten Baum unter dem div geht.

Gibt es eine einfache / elegante Möglichkeit, einen nicht-ersten Textabschnitt aus einem Elemente zu extrahieren?

War es hilfreich?

Lösung

Nun, bietet lxml.etree vollständige XPath-Unterstützung, mit der Sie die Textelemente geliefert werden können:

>>> import lxml.etree
>>> fragment = '<div>text1<span>childtext1</span>text2<span>childtext2</span>text3</div>'
>>> div = lxml.etree.fromstring(fragment)
>>> div.xpath('./text()')
['text1', 'text2', 'text3']

Andere Tipps

Ein solcher Text wird in den tail Attribute der Kinder des Elements sein. Wenn Ihr Element in elem war dann:

elem[0].tail

würden Sie den Schwanz Text des ersten Kindes innerhalb des Elements, in Ihrem Fall die "text2" die Sie suchen.

Wie llasram sagte, jeder Text nicht in dem text Attribute in dem tail Attribute des untergeordneten Knoten sein wird.

Als Beispiel ist hier die einfachste Art und Weise zu extrahieren alle der Textbrocken (ersten und anderen) in einem Knoten:

html = '<div>text1<span>childtext1</span>text2<span>childtext2</span>text3</div>'

import lxml.html    # ...or lxml.etree as appropriate
div = lxml.html.fromstring(html)

texts = [div.text] + [child.tail for child in div]
# Result: texts == ['text1', 'text2', 'text3']
# ...and you are guaranteed that div[x].tail == texts[x+1]
# (which can be useful if you need to access or modify the DOM)

Wenn Sie lieber, dass die Beziehung opfern, würde texts zu verhindern, dass möglicherweise leere Zeichenfolgen enthalten, können Sie diese stattdessen verwenden:

texts = [div.text] + [child.tail for child in div if child.tail]

Ich habe nicht getestet dies mit einfachen alten stdlib ElementTree, aber es sollte auch mit daran arbeiten. (Etwas, das fiel mir erst, wenn ich Shane Holloway lxml spezifische Lösung sah) Ich ziehe LXML, nur weil es eine bessere Unterstützung für HTML-Code der ideosyncracies bekam ist und ich in der Regel haben es bereits für lxml.html.clean installiert

Mit node.text_content() den gesamten Text unterhalb eines Knotens als einzelne Zeichenfolge zu erhalten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top