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 в этом документе показывает, что он не заканчивает ни один из этих абзацев, пока не увидит body>:
<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 (по крайней мере, до body>, после чего он должен сообщить об ошибке 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")