BeautifulSoup (bs4) неправильно анализирует

Разбор этого образца документа с помощью bs4 из Python 2.7.6:

<html>
<body>
<p>HTML allows omitting P end-tags.

<p>Like that and this.

<p>And this, too.

<p>What happened?</p>

<p>And can we <p>nest a paragraph, too?</p></p>

</body>
</html>

С помощью:

from bs4 import BeautifulSoup as BS
...
tree = BS(fh)

В течение веков в HTML допускались пропущенные конечные теги для различных типов элементов, включая P (проверьте схему или анализатор). Тем не менее, prettify() bs4 в этом документе показывает, что он не заканчивает ни один из этих абзацев, пока не увидит :

<html>
 <body>
  <p>
   HTML allows omitting P end-tags.
   <p>
    Like that and this.
    <p>
     And this, too.
     <p>
      What happened?
     </p>
     <p>
      And can we
      <p>
       nest a paragraph, too?
      </p>
     </p>
    </p>
   </p>
  </p>
 </body>

Это не ошибка prettify(), потому что, обходя дерево вручную, я получаю ту же структуру:

<[document]>
    <html>
        ␊
        <body>
            ␊
            <p>
                HTML allows omitting P end-tags.␊␊
                <p>
                    Like that and this.␊␊
                    <p>
                        And this, too.␊␊
                        <p>
                            What happened?
                        </p>
                        ␊
                        <p>
                            And can we 
                            <p>
                                nest a paragraph, too?
                            </p>
                        </p>
                        ␊
                    </p>
                </p>
            </p>
        </body>
        ␊
    </html>
    ␊
</[document]>

Теперь это будет правильный результат для XML (по крайней мере, до , после чего он должен сообщить об ошибке WF). Но это не XML. Что дает?

1 ответ

Решение

Документ на http://www.crummy.com/software/BeautifulSoup/bs4/doc/ рассказывает, как заставить BS4 использовать разные парсеры. Очевидно, по умолчанию используется html.parse, который, по словам документа BS4, не работает до Python 2.7.3, но, по-видимому, все еще имеет проблему, описанную выше в 2.7.6.

Переключение на "lxml" было для меня неудачным, но переключение на "html5lib" дает правильный результат:

tree = BS(htmSource, "html5lib")
Другие вопросы по тегам