#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, для меня это сработало идеально. Спасибо за вашу помощь