BeautifulSoup раскомментирует комментарий по id - PullRequest
1 голос
/ 28 мая 2020

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

<div class="foo">
 cat dog sheep goat
 <!--<p id="p1">test</p>-->
 <p id="p2">
  test
 </p>
</div>

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

<div class="foo">
 cat dog sheep goat
 <p id="p1">test</p>
 <p id="p2">
  test
 </p>
</div>

Это мой python код Я использую BeautifulSoup, но не знаю, как выполнить эту функцию.

from bs4 import BeautifulSoup,Comment

data = """<div class="foo">
cat dog sheep goat
<p id='p1'>test</p>
<p id='p2'>test</p>
</div>"""
soup = BeautifulSoup(data, 'html.parser')

for comment in soup(text=lambda text: isinstance(text, Comment)):
    if 'id="p1"' in comment.string: 
        # I don't know how to complete it here.
        # This is my incorrect solution
        # It will output "&lt;p id="p1"&gt;test&lt;/p&gt;",
        # not "<p id='p1'>test</p>"    
        comment.replace_with(comment.string.replace("<!--", "").replace("-->", ""))  
        break   

Обратиться за помощью

Ответы [ 2 ]

2 голосов
/ 28 мая 2020

Вы можете поместить новый суп в .replace_with() вместо строки:

from bs4 import BeautifulSoup,Comment

data = """<div class="foo">
 cat dog sheep goat
 <!--<p id="p1">test</p>-->
 <p id="p2">
  test
 </p>
</div>"""
soup = BeautifulSoup(data, 'html.parser')

print('Original soup:')
print('-' * 80)
print(soup)
print()

for comment in soup(text=lambda text: isinstance(text, Comment)):
    if 'id="p1"' in comment.string:
        tag = BeautifulSoup(comment, 'html.parser')
        comment.replace_with(tag)
        break

print('New soup:')
print('-' * 80)
print(soup)
print()

Печать:

Original soup:
--------------------------------------------------------------------------------
<div class="foo">
 cat dog sheep goat
 <!--<p id="p1">test</p>-->
<p id="p2">
  test
 </p>
</div>

New soup:
--------------------------------------------------------------------------------
<div class="foo">
 cat dog sheep goat
 <p id="p1">test</p>
<p id="p2">
  test
 </p>
</div>
0 голосов
/ 28 мая 2020

Рассматривали ли вы просто использование регулярного выражения вместо bs4?

Может быть, это поможет вам начать.

>>> re.search("<!--((.*)p1(.*))-->", '<!--<p id="p1">test</p>-->')
<re.Match object; span=(0, 26), match='<!--<p id="p1">test</p>-->'>
>>> re.search("<!--((.*)p1(.*))-->", '<!--<p id="p1">test</p>-->').group(1)
'<p id="p1">test</p>'
>>> regex = re.compile("<!--((.*)p1(.*))-->")
>>> regex.sub('<p id="p1">test</p>', '<!--<p id="p1">test</p>-->')
'<p id="p1">test</p>'
...