lxml python загрузить html строку без заголовка и тела и добавить элемент вокруг целевых элементов

Я пытаюсь использовать lxml для чтения html из строки, а затем попытаюсь найти все теги img, обновить атрибут src изображения и добавить гипер ссылку вокруг каждого найденного изображения

так что это,

<img src="old-value" /> 

будет это

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

проблема am сталкивается с двумя, сначала я использую etree.HTML для загрузки строки html, которая по какой-то причине добавляет тег html и тег body к самому html. Есть ли способ загрузить его без автоматического его возникновения?

Другая проблема, которую я не могу решить, как добавить элемент гиперссылки вокруг тега изображения, я попробовал ниже, но добавил бы элемент гиперссылки внутри тега 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) 

Кто-нибудь может посоветовать, пожалуйста?

Обновить:

Я просто попробовал подход, предоставляемый @Alko, и его работа хорошо, но у него есть проблема с типом контента, который я использую.

Тег img находится внутри p-тегов, например, пример ниже

 <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
 skjh skjh ksjh ksh skhs kjsh skjh skhs khs kjsh skjh skjhs kshk sjh 
 skjhs kjsh skjh skjh ksj ksjh jsk hskjh s</p></body></html> 

что происходит, когда я запускаю данное решение, закрытие тега добавляется после окончания абзаца.

Вы можете использовать addprevious перед вставкой:

 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) 

Это приведет к

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

Кроме того, lxml.html.fragment_fromstring может быть полезен, но вам нужно предоставить более разнообразный пример, так как в вашем случае одного элемента изображения он не будет найден вашим xpath.

См. Следующую демонстрацию:

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

Обновить

Для случая, когда img 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>' 
 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)