Прежде всего позвольте мне сказать, спасибо за размещение этого вопроса, потому что это была очень интересная проблема кодирования.
Я провел некоторое время, глядя на эту проблему, и, наконец, решил бросить ответ на ринг.
Я попытался использовать insert_before()
и insert_after()
из BeautifulSoup
, чтобы изменить тег <p>
в вашем примере HTML. Я также посмотрел на использование extend()
и append()
из BeautifulSoup
. После десятков попыток я просто не смог получить запрошенные вами результаты.
Код ниже, кажется, выполняет запрошенную модификацию HTML на основе ключевого слова (например, Дональд Туск). Я использовал replace_with()
с BeautifulSoup
для замены исходного тега в HTML на new_tag()
с BeautifulSoup.
Код работает, но я уверен, что его можно улучшить.
from bs4 import BeautifulSoup
raw_html = """
<p> This is a test. </p>
<p>The chairman of European Union leaders, Donald Tusk, will meet May in London on Thursday, a day after the bloc’s Brexit negotiator weakened sterling by issuing another warning to Britain, which is due to leave the bloc in March 2019.</p>
<p> This is also a test. </p>
"""
soup = BeautifulSoup(raw_html, 'lxml')
# find the tag that contains the keyword Donald Tusk
original_tag = soup.find('p',text=re.compile(r'Donald Tusk'))
if original_tag:
# modify text in the tag that was found in the HTML
tag_to_modify = str(original_tag.get_text()).replace('Donald Tusk,', '<span style="color:red">Donald Tusk</span>,')
print (tag_to_modify)
# outputs
The chairman of European Union leaders, <span style="color:red">Donald Tusk</span>, will meet May in London on Thursday, a day after the bloc’s Brexit negotiator weakened sterling by issuing another warning to Britain, which is due to leave the bloc in March 2019.
# create a new <p> tag in the soup
new_tag = soup.new_tag('p')
# add the modified text to the new tag
# setting a tag’s .string attribute replaces the contents with the new string
new_tag.string = tag_to_modify
# replace the original tag with the new tag
old_tag = original_tag.replace_with(new_tag)
# formatter=None, BeautifulSoup will not modify strings on output
# without this the angle brackets will get turned into “<”, and “>”
print (soup.prettify(formatter=None))
# outputs
<html>
<body>
<p>
This is a test.
</p>
<p>
The chairman of European Union leaders, <span style="color:red">Donald Tusk</span>, will meet May in London on Thursday, a day after the bloc’s Brexit negotiator weakened sterling by issuing another warning to Britain, which is due to leave the bloc in March 2019.
</p>
<p>
This is also a test.
</p>
</body>
</html>