Заменить слово в строке тегом - PullRequest
2 голосов
/ 04 апреля 2019

Давайте рассмотрим следующий фрагмент HTML:

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

Давайте превратим его в объект BeautifulSoup:

from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')

Я хотел бы преобразовать этот объект-суп, чтобы его вывод HTML был:

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

Я нашел на странице документации BeautifulSoup пару примеров того, как заменить строку, создать новый тег или даже вставить новый тег в определенном месте вдерево, , но не как добавить новый тег в середине строки , как в моем случае использования.

Любая помощь очень приветствуется.

Ответы [ 3 ]

1 голос
/ 05 апреля 2019

Прежде всего позвольте мне сказать, спасибо за размещение этого вопроса, потому что это была очень интересная проблема кодирования.

Я провел некоторое время, глядя на эту проблему, и, наконец, решил бросить ответ на ринг.

Я попытался использовать 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 “&lt;”, and “&gt;”
  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>
0 голосов
/ 04 апреля 2019

Вам необходимо использовать регулярные выражения. Надеюсь, этот фрагмент поможет.

import re

def highlight_matches(query, text):
    def span_matches(match):
        html = '<span style="color : red">{0}</span>'
        return html.format(match.group(0))
    return re.sub(query, span_matches, text, flags=re.I)
0 голосов
/ 04 апреля 2019

Попробуйте использовать цикл, просмотрите каждое слово в строке, как только вы найдете искомую строку (с помощью любого метода, регулярные выражения будут полезны), затем используйте Tag.insert (position, "found_word «)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...