【ITニュース解説】My URL-to-Markdown converter turned a paywalled article into free text — and I had to decide if that was a bug
2026年10月14日に「Dev.to」が公開したITニュース「My URL-to-Markdown converter turned a paywalled article into free text — and I had to decide if that was a bug」について初心者にもわかりやすく解説しています。
ITニュース概要
URLからMarkdownへ変換するツールが、ペイウォール記事の全文を無料で取得する問題が発生した。これは、ウェブサイトが記事全文をHTMLに含み、支払い制限をクライアント側の技術で制御していたためだ。開発者は、ツールはサーバー提供内容を正確に抽出する方針を維持。クリーンな抽出とアクセス制御の尊重は異なる機能だと学んだ。
ITニュース解説
あるシステム開発者が、特定のURL(ウェブページの住所)を入力すると、そのウェブページの主要な内容を、シンプルで読みやすいMarkdown形式(プログラマーがよく使うテキスト記述形式)に変換するAPI(異なるソフトウェア同士が連携するための仕組み)を開発した。このAPIは、大規模言語モデル(LLM)と呼ばれるAIが情報を処理しやすいように整形する「LLM-ready」な設計を目標としていた。具体的には、ウェブページから広告やナビゲーションメニュー、サイドバーなどの余計な要素を取り除き、記事の本文だけをきれいに抽出する「可読性抽出」という機能が搭載され、その機能は設計通りに動作し、全てのテストをクリアしていた。
しかし、このAPIに、通常は課金しなければ全文を読めない「ペイウォール記事」(課金制記事)のURLが入力された際、予期せぬ事態が発生した。APIは、その課金記事の全文を、まるで自由に読める記事のように完璧に抽出し、返却してしまったのだ。開発者にとって、これは自らのプログラムが設計通りに動作した結果なのか、それとも倫理的に問題のある「バグ」なのか、という難しい判断を迫られることになった。
この現象の背景には、ウェブサイトがコンテンツをユーザーに表示する方法に違いがある。多くのペイウォール記事を掲載するウェブサイトでは、実際には記事の全文データが、最初にウェブサーバーからユーザーのウェブブラウザ(ウェブページを見るためのソフトウェア)へ送信されている場合がある。しかし、ユーザーのブラウザ側で、CSS(ウェブページの見た目を定義する言語)やJavaScript(ウェブページに動きやインタラクティブな機能を追加するプログラミング言語)を用いて、その全文の上に「課金しないと読めない」という覆いをかぶせたり、記事の途中で表示を遮ったりする処理を行っているのだ。
開発者のAPIは、「サーバーサイドスクレイピング」という手法を用いていた。これは、プログラムがウェブサーバーから直接HTML(ウェブページの構造を記述する言語)データを取得する技術である。サーバーから送られてくるHTMLデータは、まだブラウザ側でCSSやJavaScriptによる隠蔽処理が施される前の「生の」状態であるため、APIはこのペイウォールの仕組みをすり抜け、記事の全文を問題なく「発見」し、抽出することができたのである。つまり、APIは「設計通り」に、サーバーが提供するコンテンツをそのまま読み取り、整形したに過ぎなかった。
この状況に直面した開発者は、いくつかの対応策を検討した。まず、CSSのdisplay:none(表示しない)という設定がされているテキストを自動的に除去することを考えた。しかし、この方法は、例えばタブ切り替えコンテンツのように、意図的に普段は隠されているが、ユーザーの操作によって表示されるべき「正当な隠しコンテンツ」まで削除してしまう可能性があるため、実用的ではないと判断された。
次に、特定のドメイン(ウェブサイトのアドレス)からのコンテンツ抽出をブロックするという案も検討された。しかし、ウェブサイトの構造やURLは頻繁に変わるため、ブロックリストを常に最新の状態に保つのは非常に困難であり、「いたちごっこ」に陥る可能性が高いと判断され、採用されなかった。
さらに、ウェブサイトを巡回するクローラー(検索エンジンのロボットなど)に対してアクセスルールを指示するrobots.txtファイルを確認するという案も検討された。しかし、多くのペイウォールサイトは、検索エンジンに記事の内容をインデックス(登録)させるために、robots.txtではクローラーのアクセスを許可している。彼らはコンテンツのアクセス制限を、JavaScriptによるブラウザ側の処理に頼っているため、robots.txtの確認は今回の問題解決には繋がらなかった。
最終的に開発者は、自分のAPIのコードそのものには変更を加えないという決断を下した。APIは、「サーバーが送るものをそのまま抽出する」という、当初の正直な基本設計を維持することにした。開発者の考えでは、記事の課金やアクセス制限を実施する責任は、コンテンツを提供しているパブリッシャー(情報公開元)のサーバー側にあるべきであり、情報を抽出する側のAPIの責任ではないと判断したのだ。もしパブリッシャーが記事の全文をHTMLとしてサーバーから送信しているのであれば、それは彼らのシステム設計上の決定である、という結論に至った。
しかし、この経験から得られた重要な教訓を活かし、開発者はAPIに一つの機能を追加した。それは、「raw(生データ)モード」と「readability(可読性)モード」という、二つの異なる抽出モードを切り替えられるようにしたことだ。そして、特にreadabilityモードについては、APIのドキュメント(説明書)に明確な注意書きを加えた。「このモードは、サーバーが提供する内容をそのまま返します。これには、ウェブサイトがクライアント側(ユーザーのブラウザ側)でアクセス制限しようとしていたコンテンツも含まれる可能性があります」と明記したのである。
この注意書きは、大規模言語モデル(LLM)のようなAIシステムを構築する際に利用される「RAGパイプライン」(外部の情報を検索・取得して、AIの回答を強化する仕組み)を開発している人々にとって、非常に重要な意味を持つ。AIは、与えられた情報(「コンテキストウィンドウ」と呼ばれる、AIが一度に処理できる情報の量)を、その内容を深く吟味することなく取り込んでしまう。そのため、開発者が意図せず課金コンテンツをAIに取り込ませてしまったり、それを基に情報を生成・再配布してしまったりする可能性があるからだ。そのような状況で、コンテンツの権利者であるパブリッシャーから問い合わせがあった際に、「APIが提供してくれたから」という説明は、責任の回避にはならない。
この出来事から得られた最も本質的な教訓は、開発者のコードの技術的な側面に関するものではなかった。「クリーンな情報抽出」という機能と、「アクセス制御の尊重」という機能は、一見関連しているようでいて、実は全く異なる二つの機能であるということだ。開発者は、前者の機能だけを完璧に実装しながら、それが同時に後者の機能も満たしていると無意識のうちに思い込んでいたのである。システム開発においては、単に技術的な要件を満たすだけでなく、それが社会や倫理、法的な側面とどのように関わるのか、深く考慮することの重要性を示す事例となった。