Python: iniezione di contenuto HTML in un tag usando `lxml.html`

Sto usando la libreria lxml.html per analizzare un documento HTML.

Ho localizzato un tag specifico, che chiamo content_tag , e voglio cambiare il suo contenuto (cioè il testo tra

e

,) e il nuovo contenuto è una stringa con qualche html, dire che è 'Hello world!' .

Come lo faccio? Ho provato content_tag.text = 'Hello world!' ma poi sfugge a tutti i tag html, sostituendo < con < eccetera.

Voglio iniettare il testo senza sfuggire a qualsiasi HTML. Come lo posso fare?

Questo è un modo:

 #!/usr/bin/env python2.6 from lxml.html import fromstring, tostring from lxml.html import builder as E fragment = """\ 
This is div.
""" div = fromstring(fragment) print tostring(div) #
#
This is div.
#
div.replace(div.get_element_by_id('inner'), E.DIV('Hello ', EB('world!'))) print tostring(div) #
#
Hello world!

Vedi anche: http://lxml.de/lxmlhtml.html#creating-html-with-the-e-factory

Edit: Quindi, avrei dovuto confessare prima che non sono così familiare con lxml. Ho esaminato brevemente i documenti e la fonte, ma non ho trovato una soluzione pulita. Forse, qualcuno più familiare si fermerà e ci metterà entrambi dritti.

Nel frattempo, sembra funzionare, ma non è ben testato:

 import lxml.html content_tag = lxml.html.fromstring('
Goodbye.
') content_tag.text = '' # assumes only text to start for elem in lxml.html.fragments_fromstring('Hello world!'): if type(elem) == str: #but, only the first? content_tag.text += elem else: content_tag.append(elem) print lxml.html.tostring(content_tag)

Modifica di nuovo: e questa versione rimuove testo e figli

 somehtml = 'Hello world!' # purge element contents content_tag.text = '' for child in content_tag.getchildren(): content_tag.remove(child) fragments = lxml.html.fragments_fromstring(somehtml) if type(fragments[0]) == str: content_tag.text = fragments.pop(0) content_tag.extend(fragments) 

Supponendo che content_tag non abbia alcun sottoelemento, puoi semplicemente:

 from lxml import html from lxml.html.builder import B ... content_tag.text = 'Hello ' content_tag.append(B('world!')) print html.tostring(content_tag) 

Dopo aver armeggiato, ho trovato questa soluzione:

 fragments = lxml.html.fragments_fromstring() last = None for frag in fragments: if isinstance(frag, lxml.etree._Element): content_tag.append(frag) last = frag else: if last: last.tail = frag else: content_tag.text = frag