• Readability.js๋Š” Firefox Reader View์—์„œ ์“ฐ์ด๋Š” ๋ณธ๋ฌธ ์ถ”์ถœ ๋กœ์ง์˜ ๋…๋ฆฝ ์‹คํ–‰ํ˜• ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  • DOM ๋…ธ๋“œ๋ฅผ ์Šค์ฝ”์–ด๋งํ•˜๋Š” ํœด๋ฆฌ์Šคํ‹ฑ์œผ๋กœ ๊ด‘๊ณ ยท๋„ค๋น„๊ฒŒ์ด์…˜ยท์‚ฌ์ด๋“œ๋ฐ”๋ฅผ ๊ฑธ๋Ÿฌ๋‚ด๊ณ  ๊ธฐ์‚ฌ ๋ณธ๋ฌธ๋งŒ ๋‚จ๊ธฐ๋Š” ํŒŒ์„œ
  • new Readability(document).parse() ํ•œ ์ค„ ํ˜ธ์ถœ๋กœ title/content/textContent/excerpt ๋“ฑ์„ ๋ฐ˜ํ™˜ํ•˜๋Š” API

ํ•ด๋‹น ๊ฐœ๋…์ด ํ•„์š”ํ•œ ์ด์œ 

  • HTML์„ ๊ทธ๋Œ€๋กœ chunkํ•˜๋ฉด nav/ads๊ฐ€ claim ์ถ”์ถœ ๋Œ€์ƒ์— ์„ž์—ฌ LLM-wiki Ingest flow์˜ claim ํ’ˆ์งˆ์ด ๋–จ์–ด์ง„๋‹ค
  • ๋ณธ๋ฌธ๋งŒ ๋‚จ๊ธฐ๋Š” ๊ฒŒ ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์—ญํ• ์ด๊ณ , ์ •์ œ๋œ HTML์„ markdown์œผ๋กœ ๋ฐ”๊พธ๋Š” ๊ฒƒ์€ Turndown.js๊ฐ€ ๋‹ด๋‹นํ•˜๋Š” ๋ณ„๊ฐœ ๋‹จ๊ณ„๋‹ค
  • HTML Ingest ๋ ˆ์ด์–ด์™€ LLM-Wiki ์ „์ฒด ๊ตฌ์กฐ์—์„œ๋Š” ์ด ์กฐํ•ฉ์„ ๊ธฐ๋ณธ ๊ตฌํ˜„์ฒด๋กœ ์“ฐ์ง€๋งŒ, ๋ ˆ์ด์–ด ์ธํ„ฐํŽ˜์ด์Šค(HTML in โ†’ ์ •๊ทœํ™” Markdown + ํ•ด์‹œ out)๋งŒ ์ง€ํ‚ค๋ฉด trafilatura ๊ฐ™์€ ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๊ต์ฒดํ•  ์ˆ˜ ์žˆ๋‹ค

AS-IS

<html>
  <nav>...๋ฉ”๋‰ด...</nav>
  <aside>...๊ด‘๊ณ ...</aside>
  <article><h1>์ œ๋ชฉ</h1><p>๋ณธ๋ฌธ...</p></article>
  <footer>...</footer>
</html>

์ „์ฒด DOM์ด ๊ทธ๋Œ€๋กœ chunk ๋Œ€์ƒ์ด ๋˜์–ด nav/aside/footer๋„ claim ํ›„๋ณด์— ์„ž์ธ๋‹ค.

TO-BE

const { document } = new JSDOM(rawHtml).window;
const article = new Readability(document).parse();
// article.content: ๋ณธ๋ฌธ HTML๋งŒ ๋‚จ์Œ (nav/aside/footer ์ œ๊ฑฐ)
// article.textContent: ๋ณธ๋ฌธ ํ…์ŠคํŠธ๋งŒ

parse() ๊ฒฐ๊ณผ ํ•„๋“œ

ํ•„๋“œ๋‚ด์šฉ
title๊ธฐ์‚ฌ ์ œ๋ชฉ
content์ •์ œ๋œ ๋ณธ๋ฌธ HTML
textContent๋ณธ๋ฌธ ์ˆœ์ˆ˜ ํ…์ŠคํŠธ
excerpt์š”์•ฝ/์„ค๋ช…
byline์ž‘์„ฑ์ž ์ •๋ณด
lang, dir, publishedTime, siteName๋ฉ”ํƒ€๋ฐ์ดํ„ฐ

์ฃผ์˜ํ•  ์  2๊ฐ€์ง€

  1. parse()๋Š” ์›๋ณธ DOM์„ ์ง์ ‘ ์ˆ˜์ •ํ•œ๋‹ค โ€” ์›๋ณธ ๋ณด์กด์ด ํ•„์š”ํ•˜๋ฉด cloneํ•œ document๋ฅผ ๋„˜๊ฒจ์•ผ ํ•œ๋‹ค
  2. Readability ์ž์ฒด๋Š” sanitize๋ฅผ ํ•˜์ง€ ์•Š๋Š”๋‹ค โ€” ์‹ ๋ขฐํ•  ์ˆ˜ ์—†๋Š” ์ž…๋ ฅ(web clipper๋กœ ์ž„์˜ ์‚ฌ์ดํŠธ๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ๊ฒฝ์šฐ ๋“ฑ)์ด๋ฉด DOMPurify ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ณ„๋„๋กœ ํ†ต๊ณผ์‹œ์ผœ์•ผ ํ•œ๋‹ค

์ฐธ๊ณ  ๋ฌธ์„œ