Skillversitas

Specifying the Parser

Beautiful Soup does not parse HTML itself; it delegates to a parser backend you choose. The second argument to the constructor selects it, and the choice affects speed, tolerance of broken markup, and which features are available.

The Three Parsers

ParserInstallCharacter
html.parserbuilt-inFast, forgiving; limited HTML5 behavior
lxmlpip install lxmlFastest, very forgiving, good for XML too
html5libpip install html5libSlowest; parses like a browser DOM

Choosing a Parser

from bs4 import BeautifulSoup

html = "<div><p>unclosed <span>text"

soup_html5 = BeautifulSoup(html, "html.parser")
soup_lxml = BeautifulSoup(html, "lxml")
soup_html5lib = BeautifulSoup(html, "html5lib")

Rules of thumb:

  • lxml for most work: fast and forgiving, and the only one that handles XML well at speed.
  • html.parser when you cannot install extra packages.
  • html5lib when you need to match exactly what a browser does with broken markup (it is much slower).

Parsing XML

For XML documents pass the lxml parser (or xml if lxml is missing). You can keep the XML declaration in the output:

xml = "<?xml version="1.0"?><feed><entry>e1</entry></feed>"
soup = BeautifulSoup(xml, "lxml")
print(soup.xmldecl if hasattr(soup, "xmldecl") else "parsed")
for e in soup.find_all("entry"):
    print(e.get_text())

Summary

The parser argument decides how your document is turned into a tree. Use lxml by default for speed and XML support, fall back to the built-in html.parser when you cannot install extras, and choose html5lib only when you need browser-faithful parsing of badly broken HTML.