Удаление ненужных внутренних тегов - PullRequest
2 голосов
/ 29 марта 2011

Мы конвертируем DOCX в HTML через какой-то внешний конвертер.Сгенерированный HTML для таблиц содержит что-то вроде этого:

<td><div><span><b>Patienten</b></span></div></td>

Теги <div> и <span> внутри TD здесь совершенно лишние.

Ожидаемый результат -

<td><b>Patienten</b></td>

Есть ли шанс удалить их разумным способом с помощью BeautifulSoup?

Ответы [ 6 ]

1 голос
/ 04 апреля 2011

То, как мы это делаем, - это использование lxml и определение родителей и детей каждого элемента.Если между родителями и детьми нет разницы в содержании текста, у нас есть ряд правил, которым мы следуем, чтобы удерживать определенных детей, бросая родителей.И затем форсирование соответствующих элементов блока. В вашем случае b является дочерним элементом span, div и td, мы знаем, что тег td является релевантным структурирующим элементом, поэтому мы избавляемся от других.Опять же, это требует тестирования текстового содержимого каждого из вложенных элементов.

1 голос
/ 29 марта 2011

Ну, теги <div> и <span> имеют структурное значение, которое нельзя автоматически угадать как «лишнее».

Ваша проблема очень похожа на оптимизацию AST (абстрактного синтаксического дерева), выполненную вкомпиляторы.Вы можете попытаться определить некоторые правила и создать SoupOptimizer, чтобы взять дерево (ваш документ) и создать оптимизированное дерево вывода.Правила могут быть следующими:

  • span (content) -> content, если span.attributes пуст
  • div (content) -> content, если div.attributes пуст

Обратите внимание, что преобразования дерева на диалектах XML можно выполнять с помощью XSLT.Просто будьте готовы вывернуть свой мозг наизнанку, прежде чем увидите свет!

0 голосов
/ 30 марта 2011

Если одного только Beautiful Soup недостаточно, вы можете прибегнуть к регулярному выражению.

import re

ch = 'sunny day<td><div><span><b>Patienten</b></span></div></td>rainy week'
# <td><b>Patienten</b></td>

RE = '(<td>)<div><span>(<b>.*?</b>)</span></div>(</td>)'

pat = re.compile(RE)

print ch
print pat.sub('\\1\\2\\3',ch)

result

sunny day<td><div><span><b>Patienten</b></span></div></td>rainy week
sunny day<td><b>Patienten</b></td>rainy week

Легко, просто, не правда ли?

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

0 голосов
/ 29 марта 2011

Мне нравится подход , предложенный @Daren Thomas , но имейте в виду, что удаление этих "бесполезных" тегов может существенно повлиять на внешний вид документа благодаря JavaScript (менее вероятно) или CSS (намного больше) вероятно, возможно, даже вероятно), который опирается на полученный HTML, чтобы следовать определенным структурным шаблонам, даже если они расточительны.

Это значительно облегчает жизнь создателю инструмента. Предположим, что у некоторой данной конструкции в DOCX есть два возможных варианта. Один из них требует большого количества шаблонов, поэтому вы можете прикрепить несколько специальных атрибутов (например, text-align или что-то подобное). Другой нет. Проще просто всегда генерировать шаблон и писать свой CSS или что-то еще с учетом этого факта.

0 голосов
/ 29 марта 2011

Вы можете переставить дерево разбора следующим образом:

from BeautifulSoup import BeautifulSoup

soup = BeautifulSoup("<td><div><span><b>Patienten</b></span></div></td>")
td = soup.td
b = soup.td.div.span.b
td.insert(0,b)
td.div.extract()
print soup
0 голосов
/ 29 марта 2011

Вы можете использовать функцию strip_tags ответа Джесси Диллона на этот вопрос

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