Domanda

Supponiamo che io sono questo tipo di codice HTML da cui ho bisogno per selezionare "text2" utilizzando lxml / ElementTree:

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

Se ho già l'elemento div come mydiv, ritorna quindi mydiv.text solo "text1".

Uso itertext () sembra problematico o ingombrante nella migliore delle ipotesi in quanto cammina l'intero albero sotto il div.

C'è un semplice / modo elegante per estrarre un non-primo blocco di testo da un elemento?

È stato utile?

Soluzione

Bene, lxml.etree fornisce pieno supporto XPath, che permette di affrontare gli elementi di testo:

>>> 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']

Altri suggerimenti

Tale testo sarà negli attributi tail dei figli di vostro elemento. Se il vostro elemento fosse in elem poi:

elem[0].tail

Vuoi dare il testo coda del primo figlio all'interno dell'elemento, nel tuo caso il "text2" che stai cercando.

Come ha detto llasram, qualsiasi testo non l'attributo text sarà nelle attributi tail dei nodi figlio.

A titolo di esempio, ecco il modo più semplice per estrarre tutti dei segmenti di testo (primo e non) in un nodo:

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)

Se si preferisce sacrificare quel rapporto al fine di evitare texts da contenente potenzialmente stringhe vuote, si potrebbe usare questo invece:

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

Non ho ancora testato questo con pianura vecchio stdlib elementtree, ma dovrebbe funzionare con quello anche. (Qualcosa che si è verificato solo a me una volta ho visto la soluzione specifica per lxml di Shane Holloway) io preferisco LXML perché ha un migliore supporto per ideosyncracies di HTML e di solito già averlo installato per lxml.html.clean

Usa node.text_content() per ottenere tutto il testo sotto un nodo come una singola stringa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top