2013-12-17 9 views
5

sto cercando di usare lxml per leggere html da una stringa e quindi provare a trovare tutti i tag img, aggiornare l'attributo dell'immagine src e aggiungere ipertesto attorno ad ogni immagine trovatolxml python carica la stringa html senza intestazione e corpo e aggiunge elemento attorno agli elementi mirati

quindi questo,

<img src="old-value" /> 

sarà presente

<a href=""><img src="new-value" /></a> 

il problema sono rivestimento è due, primo using etree.HTML per caricare la stringa html che f o qualche motivo è aggiungere tag html e body tag allo stesso html. C'è un modo per caricarlo senza che ciò avvenga automaticamente?

Un altro problema non sono in grado di risolvere, Come faccio ad aggiungere l'elemento di collegamento ipertestuale attorno al tag di immagine, ho provato il seguito, ma sarebbe aggiungere l'elemento di collegamento ipertestuale all'interno del tag img

tree = etree.HTML(self.content) 
imgs = tree.xpath('.//img') 
thm = "new-value" 
for img in imgs: 
    img.set('src', thm) 
    a = etree.Element('a', href="#") 
    img.insert(0, a) 

Uno può consigliare per favore?

aggiornamento:

ho provato l'approccio fornito da @Alko e la sua funziona bene, ma ha un problema con il tipo di contenuto sto usando.

Il tag img si trova all'interno tag p, come nell'esempio qui sotto

<html><body><p><img src="/public_media/cache/66/ed/66edd1c01e3027ba18bef9244ca8e8b4.jpg?id=31"/>jshjksh skjhs jksh skjhsj ksh jkshs kjhs kjsh sjkhs khs ksh skh skh skjh skjh skjh ksjh ksh skhs kjsh skjh skhs khs kjsh skjh skjhs kshk sjh skjhs kjsh skjh skjh ksj ksjh jsk hskjh s</p><p>jshjksh skjhs jksh skjhsj ksh jkshs kjhs kjsh sjkhs khs ksh skh skh skjh&#13; 
skjh skjh ksjh ksh skhs kjsh skjh skhs khs kjsh skjh skjhs kshk sjh &#13; 
skjhs kjsh skjh skjh ksj ksjh jsk hskjh s</p></body></html> 

che cosa sta accadendo quando ho eseguito la soluzione data, la chiusura viene aggiunto un tag dopo la fine del paragrafo.

+1

grande che inizi a usare 'LXML' ora. Potresti accettare la risposta da dove hai avuto questa idea/conoscenza - come ha risolto il tuo problema per sostituire il valore 'src': http://stackoverflow.com/questions/20595735/python-regular-expression-find-and -replace-html-tag-con-specific-attribute-valu/20629768 # 20629768 – Jon

+1

Ho appena fatto, grazie jon :) .. apprezzo il tuo input –

risposta

3

È possibile utilizzare addprevious prima dell'inserto:

imgs = tree.xpath('.//img') 
thm = "new-value" 
for img in imgs: 
    img.set('src', thm) 
    a = etree.Element('a', href="#") 
    img.addprevious(a) 
    a.insert(0, img) 

che si tradurrà in

>>> etree.tostring(tree) 
'<html><body><a href="#"><img src="new-value"/></a></body></html>' 

Inoltre, lxml.html.fragment_fromstring può essere utile, ma è necessario fornire più diversificata esempio, come nel tuo caso del solo elemento immagine, non verrà trovato dal tuo xpath.

Vedi seguente demo:

>>> import lxml.html 
>>> img = lxml.html.fragment_fromstring('<img src="old-value" />') 
>>> thm = "new-value" 
>>> img.set('src', thm) 
>>> a = etree.Element('a', href="#") 
>>> a.insert(0, img) 
>>> lxml.html.etree.tostring(a) 
'<a href="#"><img src="new-value"/></a>' 

Aggiornamento

Per un caso in cui img tag ha la coda, è possibile riassegnare a creato a tag:

>>> s = '<html><body><p><img src="old_value"/>some text</p></body></html>' 
>>> tree = etree.HTML(s) 
>>> imgs = tree.xpath('.//img') 
>>> thm = "new-value" 
>>> for img in imgs: 
...  img.set('src', thm) 
...  a = etree.Element('a', href="#") 
...  img.addprevious(a) 
...  a.insert(0, img) 
...  a.tail = img.tail 
...  img.tail = '' 
... 
>>> etree.tostring(tree) 
'<html><body><p><a href="#"><img src="new-value"/></a>some text</p></body></html>' 
+0

grazie per la risposta rapida, addprevious ha funzionato .. ma non aggiungerà tag di chiusura dopo l'immagine? per me, sto ottenendo and thats it, there is no closing dopo la img –

+0

@MoJ.Mughrabi è necessario aggiungere * e * inserire nel nuovo elemento (''), vedere esempi nella mia risposta – alko

+0

ho appena aggiornato la domanda, il problema è nello stesso html, il tag immagine si trova all'interno del tag ap che causa il a da inserire dopo il paragrafo quando si utilizza l'inserto –

0
holder = etree.Element('div', {'id': 'links'}) 
for img in imgs: 
    a_tag = etree.SubElement(holder, {'href':'#'}) 
    img_tag = etree.SubElement(a_tag, {'src': 'new_value'}) 

etree.toString(holder)