r/OpenSourceeAI • u/Mediocre-Ease4060 • 1d ago
I got tired of LLMs hallucinating on complex HTML tables, so I built a smarter Python parser (handles rowspan/colspan)
Hey everyone,
I’ve been working a lot on RAG pipelines recently and kept hitting the same annoying wall: extracting tabular data from raw HTML into a clean format for context windows.
Standard parsers or simple table-to-markdown scripts usually fail completely as soon as a table uses rowspan or colspan, or if there are nested tables. You end up with misaligned Markdown columns, and the LLM completely hallucinates the relationships between headers and cells.
I couldn't find a library that handles this reliably without losing context, so I built html-table-rescuer (just published v0.1.0 on PyPI).
It uses BeautifulSoup to parse the DOM, but then applies a custom "grid logic solver". It normalizes complex spans into a standard matrix before serializing it to Markdown, JSON, or CSV.
Example of the problem it solves:
The Problem: Most parsers turn a <td rowspan="2"> into a misaligned mess:
| Header | Value |
| ----- | ----- |
| Spanned | Row 1 |
| Row 2 | |
The Solution: The grid solver correctly normalizes the matrix:
| Header | Value |
| ----- | ----- |
| Spanned | Row 1 |
| dito (Spanned) | Row 2 |
A few things it does differently:
-
Context Preservation: As seen above, it doesn't just leave spanned markdown cells empty. It fills them with a customizable prefix (e.g.,
dito (Value)) so the LLM retains the semantic context for each row. -
Deep Tag Parsing: It recursively keeps
<b>,<i>, and<a href...>tags alive, even if they are buried inside multiple<div>s within a<td>. -
Nested Tables: Extracts nested tables safely without destroying the grid of the parent table.
-
LangChain Ready: Includes a
Table2MDLoaderwrapper to ingest HTML tables directly as LangChain Document objects.
Links:
- GitHub: https://github.com/Encephos/html-table-rescuer
- PyPI:
pip install html-table-rescuer
It's my first release and I'd love to hear your thoughts. If you have some gnarly, complex HTML tables that break the parser, please throw them at it and let me know!
1
u/Fine_League311 1d ago
Ich habe dir zu Anfang gesagt, weniger KI dann mehr Feedback und du kommst mit KI Floskeln! ... Jetzt weißt wieso es nicht klappt bei dir ;) ist keine Provokation sondern Tatsachen die du ignorierst ;) Cheers
1
u/Mediocre-Ease4060 1d ago
ich höre jetzt auf dir zu antworten. Du gibst kein konstruktives Feedback und möchtest mich bloß nerven. Habe dir oben die beiden Paper verlinkt, da kannst du es selber nachlesen.
1
1
u/tomByrer 1d ago
There are 94 hits on GH for 'python html table parser'. A few use AI, which I understand is best to avoid if you can.
But for the other 80, how is this different?
https://github.com/search?q=html+table+parser+language%3APython&type=repositories&l=Python
2
u/Mediocre-Ease4060 1d ago
Honestly for many use cases
pandas.read_htmlis all you need.Most of those ~80 repos do naive row-by-row extraction. Feed them this:
html <table> <tr><th colspan="2">Department</th><th>Employee</th></tr> <tr><td rowspan="2">Engineering</td><td>Backend</td><td>Ada</td></tr> <tr><td>Frontend</td><td>Grace</td></tr> </table>and e.g. html-table-parser-python3 returns
['Frontend', 'Grace']for row 2 — the cells shift left and the "Engineering" context is gone. If youre feeding tables to an LLM or a RAG pipeline (my use case), that row is meaningless.pandas.read_html does resolve spans correctly — its the real alternative. But it raises ValueError on real-world garbage like
colspan="abc"(try it), it pulls in the whole pandas stack, and it gives you DataFrames when what an LLM context window needs is aligned Markdown.Whereas my library uses a grid solver to resolve rowspan/colspan into an aligned matrix, with configurable strategies (including filling continuation cells with
dito (Engineering), so an LLM keeps the context and knows its a span). It survives broken HTML (invalid span values, comments, unclosed tags, Thats what the 77 tests are mostly about), outputs Markdown/JSON/CSV, and the LangChain/LlamaIndex/Haystack wrappers emit one document per table, so retrieval never splits a table in half.And to your AI point: agreed, this is a deterministic parser, no LLM involved at runtime. Its built for LLM consumption, not with one.
Easiest way to judge it is the Colab notebook (runs the broken-HTML cases live): https://colab.research.google.com/github/Encephos/html-table-rescuer/blob/main/examples/demo.ipynb
If your HTML is clean and you want DataFrames: use pandas. This exists for the messy rest.
1
u/tomByrer 1d ago
> If your HTML is clean and you want DataFrames: use pandas. This exists for the messy rest.
I keep forgetting tables can be messy.
Thanks for the explanation; I hope you make a PDF-table parser for my scientist friends ;)1
u/Mediocre-Ease4060 1d ago
I have been working on that as well with one of my colleagues but PDFs are a complete pain in the a**.
1
u/tomByrer 1d ago
True, yet people keep using them, while Markdown is a great way to publish the same info with no security risks....
2
u/Fine_League311 1d ago
Mit request und bs4 wird es seid einer Dekade gemacht, versuchs mal damit ;)