Как визуализировать встроенный элемент с помощью beautiful soup 4

#python #beautifulsoup

Вопрос:

Я преобразую тег в макрос слияния с помощью bs4

вход:

 lt;pgt; lt;img src="path/to/file.jpg" /gt; lt;/pgt;  

ожидаемый результат:

 lt;pgt;  lt;ac:image ac:align="center" ac:layout="center"gt;  lt;ri:attachment ri:filename="file.jpg" ri:version-at-save="1" /gt;  lt;/ac:imagegt; lt;/pgt;  

Вот функция, которая используется для ее достижения

 def transform_img_to_confluence(soup):  def get_image_tag(image_name):  return BeautifulSoup(textwrap.dedent('''  lt;ac:image ac:align="center" ac:layout="center"gt;  lt;ri:attachment ri:filename="{}" ri:version-at-save="1" /gt;  lt;/ac:imagegt;  ''').format(image_name), "html.parser")      for img in soup.find_all('img'):  path = img['src']  image_name = os.path.basename(path)   image_tag = get_image_tag(image_name)  img.replace_with(image_tag)  
 soup = BeautifulSoup(html_string, "html.parser") transform_img_to_confluence(soup)  print(soup.prettify())  

Когда я проверяю soup после вызова этой функции, я ожидаю, что теги будут заменены на следующие ( ri:attachment элемент как встроенный )

 lt;ac:image ac:align="center" ac:layout="center"gt;  lt;ri:attachment ri:filename="file.jpg" ri:version-at-save="1" /gt; lt;/ac:imagegt;  

но, к сожалению, вместо этого я получаю это. ( ri:attachment с открытыми и закрытыми тегами )

 lt;ac:image ac:align="center" ac:layout="center"gt;  lt;ri:attachment ri:filename="file.jpg" ri:version-at-save="1"gt;  lt;/ri:attachmentgt; lt;/ac:imagegt;  

Как убедиться, что я получаю нужный встроенный элемент ?

Ответ №1:

проблема возникает из-за синтаксического анализатора. в вашем случае lxml-xml так и должно быть. вот несколько примеров выходных данных доступных анализаторов

 from bs4 import BeautifulSoup a="""lt;agt;lt;b /gt;lt;/agt;""" print(BeautifulSoup(a, 'lxml')) gt;gt;gt; lt;htmlgt;lt;bodygt;lt;agt;lt;bgt;lt;/bgt;lt;/agt;lt;/bodygt;lt;/htmlgt;  print(BeautifulSoup(a, 'lxml-xml')) gt;gt;gt; lt;?xml version="1.0" encoding="utf-8"?gt; gt;gt;gt; lt;agt;lt;b/gt;lt;/agt;  print(BeautifulSoup(a, 'html.parser')) gt;gt;gt; lt;agt;lt;bgt;lt;/bgt;lt;/agt;  print(BeautifulSoup(a, 'html5lib')) gt;gt;gt; lt;htmlgt;lt;headgt;lt;/headgt;lt;bodygt;lt;agt;lt;bgt;lt;/bgt;lt;/agt;lt;/bodygt;lt;/htmlgt;