Как исправить отсутствующие теги ul в фрагменте html-списка с помощью Python и Beautiful Soup - PullRequest
2 голосов
/ 10 апреля 2019

Если у меня есть фрагмент html, подобный следующему:

<p><br><p>
<li>stuff</li>
<li>stuff</li>

Есть ли способ убрать это и добавить недостающие теги ul / ol, используя красивый суп или другой питонбиблиотека?

Я пытался soup.prettify(), но все осталось как есть.

Ответы [ 2 ]

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

Не похоже, что есть встроенный метод, который упаковывает группы из li элементов в ul. Однако вы можете просто зациклить элементы li, идентифицировать первый элемент каждой группы li и обернуть его тегами ul. Следующие элементы в группе добавляются к ранее созданному ul:

from bs4 import BeautifulSoup

soup = BeautifulSoup(html, "html.parser")

ulgroup = 0
uls = []
for li in soup.findAll('li'):
        previous_element = li.findPrevious()
        # if <li> already wrapped in <ul>, do nothing
        if previous_element and previous_element.name == 'ul': 
            continue 
        # if <li> is the first element of a <li> group, wrap it in a new <ul>
        if not previous_element or previous_element.name != 'li':
            ulgroup += 1
            ul = soup.new_tag("ul")
            li.wrap(ul)
            uls.append(ul)
        # append rest of <li> group to previously created <ul>
        elif ulgroup > 0:
            uls[ulgroup-1].append(li)

print(soup.prettify())

Например, следующий ввод:

html = '''
<p><br><p>
<li>stuff1</li>
<li>stuff2</li>
<div></div>
<li>stuff3</li>
<li>stuff4</li>
<li>stuff5</li>
'''

выходы:

<p>
 <br/>
 <p>
  <ul>
   <li>
    stuff1
   </li>
   <li>
    stuff2
   </li>
  </ul>
  <div>
  </div>
  <ul>
   <li>
    stuff3
   </li>
   <li>
    stuff4
   </li>
   <li>
    stuff5
   </li>
  </ul>
 </p>
</p>

Демо: https://repl.it/@glhr/55619920-fixing-uls

0 голосов
/ 11 апреля 2019

Сначала вы должны решить, какой синтаксический анализатор вы собираетесь использовать.Различные парсеры по-разному обрабатывают искаженный html .

Следующие методы BeautifulSoup помогут вам выполнить то, что вам нужно

  • new_tag () - создать новый тег ul

  • append () - Комудобавьте вновь созданный тег ul где-нибудь в дереве супа.

  • extract () - чтобы извлечь теги li по одному(который мы можем добавить к тегу ul)

  • декомпозировать () - удалить ненужные теги из дерева.Который может быть сформирован в результате интерпретации парсером искаженного html.

Мое решение

Давайте создадим объект супа, используя html5lib парсер, и посмотрим, что мыget

from bs4 import BeautifulSoup
html="""
<p><br><p>
<li>stuff</li>
<li>stuff</li>
"""
soup=BeautifulSoup(html,'html5lib')
print(soup)

Выходы:

<html><head></head><body><p><br/></p><p>
</p><li>stuff</li>
<li>stuff</li>
</body></html>

Следующий шаг может варьироваться в зависимости от того, чего вы хотите достичь.Я хочу удалить второй пустой р.Добавьте новый тег ul и получите все теги li внутри него.

from bs4 import BeautifulSoup
html="""
<p><br><p>
<li>stuff</li>
<li>stuff</li>
"""
soup=BeautifulSoup(html,'html5lib')
second_p=soup.find_all('p')[1]
second_p.decompose()
ul_tag=soup.new_tag('ul')
soup.find('body').append(ul_tag)
for li_tag in soup.find_all('li'):
    ul_tag.append(li_tag.extract())
print(soup.prettify())

Выходы:

<html>
 <head>
 </head>
 <body>
  <p>
   <br/>
  </p>
  <ul>
   <li>
    stuff
   </li>
   <li>
    stuff
   </li>
  </ul>
 </body>
</html>
...