Fix scraper dropping characters from CSS pseudo-element anti-scraping techniques#7
Conversation
Sites like DW.com use ::before/::after pseudo-elements to inject characters (e.g. the letter 't') as an anti-scraping measure. The previous implementation cloned the DOM and used textContent, which never sees pseudo-element content. The new getAllTextContent() works on the live DOM and uses getComputedStyle() to read ::before/::after content for every element, ensuring characters rendered only through CSS pseudo-elements are included in the extracted text. Noise filtering and fallback logic are preserved. Agent-Logs-Url: https://github.com/philffm/ai-summary-helper/sessions/c31ded7c-9ceb-4868-b60e-fb3c2d3bcdab Co-authored-by: philffm <6079545+philffm@users.noreply.github.com>
…rity Agent-Logs-Url: https://github.com/philffm/ai-summary-helper/sessions/c31ded7c-9ceb-4868-b60e-fb3c2d3bcdab Co-authored-by: philffm <6079545+philffm@users.noreply.github.com>
… XSS in debug panel Agent-Logs-Url: https://github.com/philffm/ai-summary-helper/sessions/c31ded7c-9ceb-4868-b60e-fb3c2d3bcdab Co-authored-by: philffm <6079545+philffm@users.noreply.github.com>
…mplify isNoise to O(1) Agent-Logs-Url: https://github.com/philffm/ai-summary-helper/sessions/c31ded7c-9ceb-4868-b60e-fb3c2d3bcdab Co-authored-by: philffm <6079545+philffm@users.noreply.github.com>
Agent-Logs-Url: https://github.com/philffm/ai-summary-helper/sessions/c31ded7c-9ceb-4868-b60e-fb3c2d3bcdab Co-authored-by: philffm <6079545+philffm@users.noreply.github.com>
|
@copilot Regarding your content.js script, the text extraction issues likely stem from how modern sites (like the one in your example) render fonts and handle white space. Here is a breakdown of the bugs I've identified and the corrected code. 🛠 Critical Bug Fixes
Fix: Use innerText instead of textContent. innerText is "aware" of the rendered state of the text and generally handles spacing and hidden elements much better. Regex Fix: Your regex .replace(/\n\s*\n/g, '\n\n') uses double backslashes which, inside a string, results in a literal backslash and the letter "n" rather than a newline character.
🚀 Optimized content.js JavaScript |
…arkdownToHtml() with list and inline-code support Agent-Logs-Url: https://github.com/philffm/ai-summary-helper/sessions/7a278b63-2038-4ef9-8ebd-ac4e23839dae Co-authored-by: philffm <6079545+philffm@users.noreply.github.com>
Two of the points are addressed in commit
Markdown parser refactored — the duplicate inline conversion was extracted into a shared On On Gemini stream handling: the existing defensive |
Sites like DW.com inject characters (e.g. every
t) via CSS::before/::afterpseudo-elements as an anti-scraping measure. The previous extractor cloned the DOM and readtextContent, which never sees pseudo-element content — producing garbled output like"Palan ir","in elligence","sof ware".Changes
Rewrote
getAllTextContent()to operate on the live DOM instead of a detached clone, enablingwindow.getComputedStyle()access for pseudo-element inspection.getPseudoContent(el, pseudo)— reads computed::before/::aftercontent, strips outer CSS quote wrapping via matched-pairslice(1, -1), and discards icon-font glyphs from Unicode Private Use Area (BMP U+E000–U+F8FF and supplementary planes via surrogate pairs[\uDB80-\uDBFF][\uDC00-\uDFFF]).extractText(el)— recursive DOM walker that merges text nodes with pseudo-element text at each element.noiseSet+isNoise(el)— replaces the old clone-mutate-and-delete approach: pre-computes aSetof all noise container elements (nav, header, footer, etc.) once;isNoise()becomes an O(1) lookup since the recursive structure guarantees no noise ancestors above the current node.Fixed pre-existing
/\\n/gregex bug in the streaming and final render paths: the pattern was matching the literal two-character sequence\+ninstead of actual newline characters, so LLM output newlines were never converted to<br>tags. Corrected to/\n/g.markdownToHtml()helper — extracted the duplicate inline markdown-to-HTML conversion into a shared function, adding unordered list support (*/-→<li>wrapped in<ul>) and inline code support (`code`→<code>).Fixed pre-existing XSS in
updateDebugPanel()(CodeQLjs/xss-through-dom): replacedpanel.innerHTML = \...${apiUrl}...${text}...`with structured DOM construction usingtextContent`.