Rewritten as a tested cheat sheet. Every snippet below was run by the example package against one fixture page on beautifulsoup4 4.15.0, and the output is copied from that run. The 2024 version had no captured output (only inline # Output: comments), used the text= argument that has warned since 4.11, passed from_encoding to a str (ignored), and called pd.read_html with a string that pandas 3 now treats as a filename; all corrected. New: parsers compared on broken markup, a CPU-time table with min/median/max columns and a note on how much such timings move under load, the 4.13–4.15 deprecations captured with a type-checked example, and the errors you will actually see.
Updated 2026-10-23: added a section that fetches the HTML through the ScrapingAnt API before parsing, run once against books.toscrape.com.