Проблемы с получением тега с родительским именем, идентичным дочернему, с использованием Beautifulsoup

#python #beautifulsoup

#python #beautifulsoup

Вопрос:

Это мой простой и сложный код:

 <html>
   ...
   <p>
      <font style="vertical-align: inherit;">
         <font style="vertical-align: inherit;">
            Hello
         </font>
      </font>
   </p>
   <div>
      ...
   </div>
   <p>
      <font style="vertical-align: inherit;">
         <font style="vertical-align: inherit;">
            Hello
         </font>
      </font>
   </p>
   ...
</html>
  

И мне нужно получить эти 2 тега, а затем удалить всех их <p></p> родителей

 <font style="vertical-align: inherit;">
   Hello
</font>

<font style="vertical-align: inherit;">
   Hello
</font>
  

Мое неправильное решение

 for x in soup.find_all('font', string='Hello'):
   x.find_parent("p").decompose()
  

Но с этими неполными условиями итерация выполняется 2 раза для каждого тега из-за 2 идентичных родителей:

 <font style="vertical-align: inherit;">
      <font style="vertical-align: inherit;">
  

затем во второй раз он не находит родительский элемент, потому что он уже был удален, и возникает ошибка

Комментарии:

1. Существует много потенциальных решений. Например, вы могли бы составить список элементов для удаления и сделать это только после того, как закончите перебирать результаты soup.find_all() .

Ответ №1:

Одним из возможных решений является поиск NavigableString вместо тега. Например:

 from bs4 import BeautifulSoup

html_doc = '''
<html>
   <p>
      <font style="vertical-align: inherit;">
         <font style="vertical-align: inherit;">
            Hello
         </font>
      </font>
   </p>
   <div>
    Something else.
   </div>
   <p>
      <font style="vertical-align: inherit;">
         <font style="vertical-align: inherit;">
            Hello
         </font>
      </font>
   </p>
</html>
'''

soup = BeautifulSoup(html_doc, 'html.parser')

for font in soup.find_all(text=lambda t: t.parent.name=='font' and t.strip()=='Hello'):
    font.find_parent('p').decompose()

print(soup.prettify())
  

С принтами:

 <html>
 <div>
  Something else.
 </div>
</html>
  

Комментарии:

1. Я начинаю с python и scraping, для меня это сработало идеально. Спасибо за вашу помощь