[PR #5548] [CLOSED] Markdown web scraper #5476

Closed
opened 2026-06-05 15:21:28 -04:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/Mintplex-Labs/anything-llm/pull/5548
Author: @shatfield4
Created: 4/28/2026
Status: Closed

Base: masterHead: feat/markdown-web-scraping


📝 Commits (6)

  • 185e48b convert web scraper to markdown
  • 111212a filter hidden elements and empty anchors from web scraper output
  • 337afd8 Merge branch 'master' into feat/markdown-web-scraping
  • bbfc94c use node-html-parser in flattenTables for consistency
  • e98322d Merge branch 'master' into feat/markdown-web-scraping
  • 8e7ce3e Merge branch 'master' into feat/markdown-web-scraping

📊 Changes

4 files changed (+170 additions, -33 deletions)

View changed files

📝 collector/package.json (+1 -0)
📝 collector/processLink/convert/generic.js (+27 -4)
collector/utils/htmlToMarkdown/index.js (+131 -0)
📝 collector/yarn.lock (+11 -29)

📄 Description

Pull Request Type

  • feat (New feature)
  • 🐛 fix (Bug fix)
  • ♻️ refactor (Code refactoring without changing behavior)
  • 💄 style (UI style changes)
  • 🔨 chore (Build, CI, maintenance)
  • 📝 docs (Documentation updates)

Relevant Issues

connect #5620
resolves #

Description

  • Switches the web scraper from using innerText to innerHTML and converts the HTML to markdown using node-html-markdown
  • Solves issues with LLMs hallucinating links because the current way this works is we strip all links from the page and only would keep text
  • This PR now allows us to have links and tables in markdown format giving LLMs much better context when doing things like deep research or chained agent actions to navigate to other links

Investigation:

  • markdown scrape was inflating tokens ~87% on Framer-built sites because Framer renders every responsive breakpoint in the same DOM, so innerHTML captures 3 copies of every paragraph and link while old innerText skipped CSS-hidden ones
  • added a DOM visibility filter in the puppeteer evaluate that drops display:none, visibility:hidden, and aria-hidden subtrees before serializing, so markdown matches what was on screen
  • added stripHiddenAttrs as a safety net for the fetch fallback path where computed styles aren't available
  • added stripEmptyAnchors to drop empty anchors from patterns since a link with no anchor text wastes tokens
  • tried a markdown-level dedupe pass, worked great on Framer (anythingllm.com went from +87% to +1.8%) but collapsed 30+ legitimately distinct brand entries on a portfolio site that shared short repeated labels like "Branding", "Deck", "3 Weeks"
  • tested dedupe on a non-Framer site (stripe.com), only saved 40 tokens out of 2,800 with zero unique URLs lost, basically idle
  • conclusion: dedupe was a Framer-specific bandaid with real false-positive risk on listing/portfolio pages, the DOM visibility filter is the correct fix and catches breakpoint duplicates at source

Visuals (if applicable)

Additional Information

Developer Validations

  • I ran yarn lint from the root of the repo & committed changes
  • Relevant documentation has been updated (if applicable)
  • I have tested my code functionality
  • Docker build succeeds locally

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/Mintplex-Labs/anything-llm/pull/5548 **Author:** [@shatfield4](https://github.com/shatfield4) **Created:** 4/28/2026 **Status:** ❌ Closed **Base:** `master` ← **Head:** `feat/markdown-web-scraping` --- ### 📝 Commits (6) - [`185e48b`](https://github.com/Mintplex-Labs/anything-llm/commit/185e48bc1be28111082f0673d060586fa158fe2b) convert web scraper to markdown - [`111212a`](https://github.com/Mintplex-Labs/anything-llm/commit/111212a673202521694e50b15fe24d6c9193a165) filter hidden elements and empty anchors from web scraper output - [`337afd8`](https://github.com/Mintplex-Labs/anything-llm/commit/337afd84d46cfd7dc8c7e1b867a99a7566e3bc70) Merge branch 'master' into feat/markdown-web-scraping - [`bbfc94c`](https://github.com/Mintplex-Labs/anything-llm/commit/bbfc94c48b07ac3528068b42e2ea559759010b91) use node-html-parser in flattenTables for consistency - [`e98322d`](https://github.com/Mintplex-Labs/anything-llm/commit/e98322d5b6586d1b9ab6c6083619f1cc305e16f2) Merge branch 'master' into feat/markdown-web-scraping - [`8e7ce3e`](https://github.com/Mintplex-Labs/anything-llm/commit/8e7ce3e57685ba1e3543cf76ff308a5fbbb0e390) Merge branch 'master' into feat/markdown-web-scraping ### 📊 Changes **4 files changed** (+170 additions, -33 deletions) <details> <summary>View changed files</summary> 📝 `collector/package.json` (+1 -0) 📝 `collector/processLink/convert/generic.js` (+27 -4) ➕ `collector/utils/htmlToMarkdown/index.js` (+131 -0) 📝 `collector/yarn.lock` (+11 -29) </details> ### 📄 Description ### Pull Request Type <!-- For change type, change [ ] to [x]. --> - [x] ✨ feat (New feature) - [ ] 🐛 fix (Bug fix) - [ ] ♻️ refactor (Code refactoring without changing behavior) - [ ] 💄 style (UI style changes) - [ ] 🔨 chore (Build, CI, maintenance) - [ ] 📝 docs (Documentation updates) ### Relevant Issues <!-- Use "resolves #xxx" to auto resolve on merge. Otherwise, please use "connect #xxx" --> connect #5620 resolves # ### Description <!-- Describe the changes in this PR that are impactful to the repo. What problem does it solve? --> - Switches the web scraper from using `innerText` to `innerHTML` and converts the HTML to markdown using `node-html-markdown` - Solves issues with LLMs hallucinating links because the current way this works is we strip all links from the page and only would keep text - This PR now allows us to have links and tables in markdown format giving LLMs much better context when doing things like deep research or chained agent actions to navigate to other links Investigation: - markdown scrape was inflating tokens ~87% on Framer-built sites because Framer renders every responsive breakpoint in the same DOM, so innerHTML captures 3 copies of every paragraph and link while old innerText skipped CSS-hidden ones - added a DOM visibility filter in the puppeteer evaluate that drops display:none, visibility:hidden, and aria-hidden subtrees before serializing, so markdown matches what was on screen - added stripHiddenAttrs as a safety net for the fetch fallback path where computed styles aren't available - added stripEmptyAnchors to drop [](url) empty anchors from <a><img alt=""></a> patterns since a link with no anchor text wastes tokens - tried a markdown-level dedupe pass, worked great on Framer (anythingllm.com went from +87% to +1.8%) but collapsed 30+ legitimately distinct brand entries on a portfolio site that shared short repeated labels like "Branding", "Deck", "3 Weeks" - tested dedupe on a non-Framer site (stripe.com), only saved 40 tokens out of 2,800 with zero unique URLs lost, basically idle - conclusion: dedupe was a Framer-specific bandaid with real false-positive risk on listing/portfolio pages, the DOM visibility filter is the correct fix and catches breakpoint duplicates at source ### Visuals (if applicable) <!-- Add screenshots or screen recordings to demonstrate the changes, especially for UI updates. --> ### Additional Information <!-- Add any other context about the Pull Request here that was not captured above. --> ### Developer Validations <!-- All of the applicable items should be checked. --> - [x] I ran `yarn lint` from the root of the repo & committed changes - [x] Relevant documentation has been updated (if applicable) - [x] I have tested my code functionality - [x] Docker build succeeds locally --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-06-05 15:21:28 -04:00
yindo closed this issue 2026-06-05 15:21:29 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Mintplex-Labs/anything-llm#5476