Как я могу предотвратить закрытие тегов в плохом HTML с помощью BeautifulSoup (python)? - PullRequest
4 голосов
/ 19 сентября 2011

Я автоматически перевожу содержимое страниц HTML на другой язык, поэтому мне приходится извлекать все текстовые узлы из разных страниц HTML, которые иногда плохо написаны (у меня нет возможности редактировать эти HTML).

Используя BeautifulSoup, я могу легко извлечь эти тексты и заменить их переводом, но когда я отображаю HTML после этих операций: html = BeautifulSoup (source_html) - иногда это происходит из-за того, что BeautifulSoup автоматически закрывает теги (например, тег таблицы закрывается в неправильном месте) .

Есть ли способ запретить BeautifulSoup закрывать эти теги?

Например, это мой ввод:

html = "<table><tr><td>some text</td></table>" - закрытие tr отсутствует

после супа = BeautufulSoup (html) я получаю "<table><tr><td>some text</td></tr></table>"

и я хочу получить тот же HTML, что и входные данные ...

Возможно ли это вообще?

1 Ответ

3 голосов
/ 19 сентября 2011

BeautifulSoup превосходен в разборе и извлечении данных из плохо отформатированного HTML / XML, но если разбитый HTML является неоднозначным, он использует набор правил для интерпретации тегов (что может быть не тем, что вы хотите) , См. Раздел Синтаксический анализ HTML в документации, который заканчивается примером, очень похожим на вашу ситуацию.

Если вы знаете, что не так с вашими тегами, и понимаете правила, которые использует BeautifulSoup, вы можете немного улучшить свой HTML (возможно, удалить или переместить определенные теги), чтобы BeautifulSoup возвращал желаемый результат.

Если вы можете опубликовать краткий пример, кто-то может оказать вам более конкретную помощь.


Обновление (некоторые примеры)

Например, рассмотрим пример, приведенный в документации (ссылка выше):

from BeautifulSoup import BeautifulSoup
html = """
<html>
<form>
 <table>
 <td><input name="input1">Row 1 cell 1
 <tr><td>Row 2 cell 1
 </form> 
 <td>Row 2 cell 2<br>This</br> sure is a long cell
</body> 
</html>"""
print BeautifulSoup(html).prettify()

Тег <table> будет закрыт до </form>, чтобы обеспечить правильное вложение таблицы в форму, оставляя последний <td> зависшим.

Если мы понимаем проблему, мы можем получить правильную закрывающую вкладку (</table>), удалив "<form>" перед анализом:

>>> html = html.replace("<form>", "")
>>> soup = BeautifulSoup(html)
>>> print soup.prettify()
<html>
 <table>
  <td>
   <input name="input1" />
   Row 1 cell 1
  </td>
  <tr>
   <td>
    Row 2 cell 1
   </td>
   <td>
    Row 2 cell 2
    <br />
    This
    sure is a long cell
   </td>
  </tr>
 </table>
</html>

Если тег <form> важен, вы все равно можете добавить его после анализа. Например:

>>> new_form = Tag(soup, "form")  # create form element
>>> soup.html.insert(0, new_form)  # insert form as child of html
>>> new_form.insert(0, soup.table.extract()) # move table into form
>>> print soup.prettify()
<html>
 <form>
  <table>
   <td>
    <input name="input1" />
    Row 1 cell 1
   </td>
   <tr>
    <td>
     Row 2 cell 1
    </td>
    <td>
     Row 2 cell 2
     <br />
     This
     sure is a long cell
    </td>
   </tr>
  </table>
 </form>
</html>
...