世界を動かす技術を、日本語で。

Show HN: Defuddle、Readabilityの代替となるHTMLからMarkdownへの変換ツール

概要

  • Defuddle はウェブページから不要な要素を除去し、主要コンテンツのみを抽出する JavaScriptライブラリ です。
  • Obsidian Web Clipper 用に開発され、HTMLからMarkdown変換にも最適です。
  • Mozilla Readability の代替として、より柔軟で一貫した出力を提供します。
  • Node.jsブラウザ の両方で利用可能で、CLIツールも用意されています。
  • クリーンなHTML・Markdown出力や、豊富なメタデータ抽出が特長です。

Defuddle: ウェブページから主要コンテンツを抽出する新しいツール

Defuddleとは

  • Defuddle は、ウェブページから コメント、サイドバー、ヘッダー、フッター などの不要な要素を除去し、 主要な本文のみを抽出 するライブラリ 提案
  • クリーンで一貫性のある HTMLドキュメント出力 を目指し、 Obsidian Web Clipper のために開発 確認
  • HTML→Markdown変換 ツール(例:Turndown)への入力にも適している 提案
  • Mozilla Readability の代替として利用可能で、より柔軟な出力やメタデータ抽出機能を持つ 比較
  • オープンソース で、CLIツールも提供 導入

主な特徴

  • 不要な要素(コメント、広告、SNSボタンなど)を 正確に除去 し、本文だけを残すこと 整理
  • 脚注、数式、コードブロック なども標準化して出力 標準化
  • モバイル用スタイル を参考に、不要な要素を自動判別 自動判別
  • schema.org などのリッチメタデータも抽出 データ抽出
  • Markdown変換 や、 タイトル・著者・公開日 などの情報も取得可能 情報取得

インストール方法

  • npmを利用して Defuddle をインストール
    npm install defuddle
    
  • Node.jsで利用する場合は、 JSDOM もインストール
    npm install jsdom
    
  • package.jsontype"module"に設定すること 設定

使い方

  • ブラウザ の場合

    • import { Defuddle } from 'defuddle';でインポート 導入
    • const defuddle = new Defuddle(document);で現在のドキュメントを解析 解析
    • const result = defuddle.parse();で結果を取得 結果取得
    • console.log(result.content);などで本文やメタデータを出力 出力
  • Node.js の場合

    • JSDOMとDefuddleをインポートし、HTML文字列やURLから解析 解析
    • オプションで デバッグ、Markdown変換、URL指定 などが可能 オプション利用

返却されるプロパティ

  • author (著者名)、 content (本文)、 description (概要)、 domain (ドメイン名)
  • favicon (ファビコンURL)、 image (メイン画像URL)、 metaTags (メタタグ情報)
  • parseTime (解析時間)、 published (公開日)、 site (サイト名)
  • schemaOrgData (schema.orgデータ)、 title (タイトル)、 wordCount (語数) 情報取得

バンドルの種類

  • Core bundle(defuddle) :ブラウザ用、依存なし、標準的な用途向け 推奨
  • Full bundle(defuddle/full) :数式解析機能追加、MathML⇔LaTeX変換も対応 拡張
  • Node.js bundle(defuddle/node) :JSDOM利用、Markdown変換や数式処理も完全対応 Node.js向け

オプション設定

  • debug :デバッグログを有効化 ログ確認
  • url :解析対象ページのURLを指定 URL指定
  • markdown :Markdownへの変換を有効化 変換
  • separateMarkdown :HTMLとMarkdownを分けて返却 分離
  • removeExactSelectors/PartialSelectors :広告やSNSボタンなどの除去対象を細かく制御 制御

デバッグモード

  • デバッグモード を有効にすると、詳細なログや、HTML属性の保持、divの構造維持などが可能 詳細確認

HTML標準化の詳細

  • 見出し :H1/H2がタイトルと一致すれば削除、H1はH2へ変換、アンカーリンクは除去 標準化
  • コードブロック :行番号やハイライトを除去し、言語情報は属性として保持 整理
  • 脚注 :インライン参照や本文末の脚注を標準フォーマットに変換 統一
  • 数式 :MathJaxやKaTeXもMathMLへ変換、LaTeX表現も属性で保持 変換

開発・ビルド方法

  • Node.jsnpm が必要 必要条件
  • npm installで依存関係インストール 導入
  • npm run buildでビルド ビルド

CLIツールと参考リンク


Defuddle は、 Read-it-laterアプリWebクリッピング ツールの開発者にとって、 主要コンテンツ抽出・変換 の新たな選択肢となります。 導入検討

Hackerたちの意見

Pythonの類似品はしっかりメンテナンスされてるみたいだね。数年前に自分でReadabilityアルゴリズムを実装したけど、そっちをやめて、今は定期的に更新してるスクレイパーがいくつか動いてるよ。

特におすすめのものはある?

最近これについて調べてたんだけど、いろんな言語のReadability実装の質にはあまり感心しなかったな。Readability.jsが明らかに一番良かったけど、JavaScriptだから自分のプロジェクトには合わなかった。結局、pythonのtrafilaturaライブラリを見つけて、質の高いコンテンツを正確なメタデータとともに抽出できたよ。自分の実装とtrafilaturaを比べてみると、改善の余地があるかもしれないね。

ライブラリの参考リンク: https://trafilatura.readthedocs.io/en/latest/ 興味がある人のために: Trafilaturaはイタリア語で「押出し」を意味するよ。この方法は、ソースを持つ特別なパスタtrafilataを区別する多孔質の表面を作るんだ。maccheroni trafilatiとmaccheroni lisciを比べてみてね :) (ちなみに、trifaturaじゃなくてtrafilaturaって言いたかったんだと思うよ)

...Javascriptだと俺のプロジェクトには合わなかったんだ。もしGoを使ってるなら、Readability[0]とTrafilatura[1]のGoポートを管理してるよ。どちらもアクティブにメンテされてて、Trafilaturaの抽出性能はPython版に匹敵するよ。 [0]: https://github.com/go-shiori/go-readability [1]: https://github.com/markusmobius/go-trafilatura

ちょっと古いけど、数年前にいくつかのウェブ抽出ツールをベンチマークしたことがあるよ。https://github.com/Nootka-io/wee-benchmarking-tool、当時はresiliparse-plainが明らかに勝者だった。

Obsidian Web Clipperのソースコードを見てたんだけど、マークダウン変換の結果にかなり感心して、Defuddleを見つけたよ。自分のカスタムの「後で読む」/ナレッジベースアプリで使う予定だから、ありがとうね :D

Obsidian Web Clipperにはめっちゃ満足してる!一つだけ、公開日をインポートするのがうまくいかなかったけど(それは全然許せる範囲だよ!)

Obsidian Web Clipperは、chatGPTの会話をマークダウンに変換するのにすごく便利だし、ただ印刷するためにも使えるよ(信じて、これもユーザーケースだよ)

ChatGPTに要約とか必要なものをマークダウンファイルで提供してもらうだけだよ。

他のクライアントについてはわからないけど、Kagi Assistantは会話をマークダウンとして保存するオプションを直接提供してるよ。Obsidianのウェブクリッパーを使うのもいいアイデアだね。

それって有料のプラグインなの?

MozillaのReadabilityは本当に放置されてるの?最新のリリース(v0.6.0)はたった2ヶ月前だし、メンテナーのGijsは問題に対してかなりアクティブに対応してるよ。

あのコードベースは本当に改善の余地があるね。バグを修正するために仕事用にフォークしなきゃならなかったよ。1つのバグは、数字の間にカンマがある外国語(オランダ語だと思う)を見つけると、ページ上の価格がたくさんあると、全ての数字を関連するテキストだと思っちゃうんだ。もちろん、プルリクエストを開いてマージしてもらおうとしたけど、テストが必要で、テストは俺がテストしてるページでは動かないんだよね。ほんとにめんどくさいと思う。

Obsidianのクリッパーを出た時から使ってるけど、これめっちゃ便利だよ。ウェブサイトごとのプロファイルベースの抽出が素晴らしい。Obsidianユーザーじゃなくても、マークダウンの抽出品質は見た中で一番信頼できる。

アドバイスありがとう!

なんで読者モードが一部のウェブサイトで機能しないのか知ってる人いる?普通のテキストがたくさんある記事なのに、完全に真っ白なページが出てくる(iPhoneのリーダーで)。たいていはニュースサイトなんだけど、これってサイトが意図的にコンテンツを隠して広告を表示できるようにしてるのかな?もしそうなら、どうやってるんだろう?

クッキーや「あなたのプライバシーを大切にします」バナーが原因になってることが多いよ、特にEU / UK / カリフォルニアにいる場合[1]。いくつかのウェブサイトでは、コンテンツを隠すモーダルが表示されるけど、リーダーモードは通常それにもうまく対処できる。でも他のサイトでは、リダイレクトやサーバーサイドでレンダリングされてることもあるんだ。リーダーモードが機能しない場合は、まずそれを閉じてから再試行してみて。

すごくいい仕事だね。JSDOMの例を挙げてくれてありがとう。まさに俺がreadabilityを使うときのやり方だし、これなら簡単に置き換えられそうだ。質問なんだけど、どうやってこれを検証したの?readabilityよりも良いって言ってるけど、リポジトリには精度やカバレッジを評価するためのテストやデータセットが見当たらないよ。それも共有してもらえる?

現在は手動テストとユーザーからのフィードバックに頼ってるけど、はい、テストを追加したいと思ってる。DefuddleはReadabilityとはかなり違う動き方をするんだ。Readabilityはちょっと保守的すぎて、"メイン"コンテンツの始まりと終わりを見つけるためにブロックをテストするから、役に立つコンテンツを削除しちゃうことがある。Defuddleは複数回のパスを実行して、コンテンツが返ってこなかった場合に結果を拡張しようとすることができるんだ。それに、コンテンツをクリーンアップするためにより多様なテクニックを使っていて、例えばページのモバイルスタイルを使って隠せるコンテンツを検出することもできる。最後に、Defuddleはコンテンツを抽出するだけじゃなくて、出力を標準化することもしてる(Readabilityはこれをやってない)。例えば、脚注やコードブロックはすべて単一のフォーマットで出力することを目指してるけど、Readabilityは元のDOMをそのままにしてるんだ。

いいね。俺も似たようなものを探してるんだけど、HTMLメールから署名や定型文の免責事項を取り除くためのやつ。これでできるかな?