【ITニュース解説】Your scraper's filter did nothing, and the run looked perfect
2026年10月24日に「Dev.to」が公開したITニュース「Your scraper's filter did nothing, and the run looked perfect」について初心者にもわかりやすく解説しています。
ITニュース概要
データ収集ツールで、選択したモードで無効なフィルターを指定すると、エラーが出ずに無視される問題があった。これにより、意図せず全データが取得され、不要なコストが発生する。フィルターが無効な場合は明確に警告を出すよう修正し、ユーザーが誤解しないようにした。
ITニュース解説
IT分野におけるデータ収集プログラム、一般にはスクレイパーと呼ばれるものが多岐にわたるデータを扱う際、特定の動作モードでしか有効ではないフィルターの扱いが問題となる場合がある。これは、プログラムが複数のデータ種類(例えば、製品のレビュー情報と、関連するエピソード情報など)を扱う能力を持っているときに特に顕著に現れる問題である。ユーザーが意図しないフィルターを誤って指定しても、プログラムがそれを黙って無視してしまうと、重大な結果を招くことがある。
具体的な例として、Apple Podcastsの情報を収集するプログラムを考えてみよう。このプログラムは、レビュー情報とエピソード情報の両方を取得できる。レビュー情報を取得するモードでは、「キーワード」「最低評価」「最高評価」「並べ替え順」といったフィルターが有効だ。一方、エピソード情報を取得するモードでは、「最低期間(秒)」「明示的なコンテンツの有無」「リリース日」といったフィルターが利用できる。これらのフィルターは、プログラムの設計図(スキーマ)上ではすべてが有効な入力として定義されているため、ユーザーはどちらのモードでも利用できるものだと誤解しやすい。
ここで問題が発生するのは、例えばプログラムを「エピソード情報取得モード」で動かしているにもかかわらず、「レビュー情報取得モード」でしか意味のない「キーワード:”AI”」というフィルターを渡した場合だ。エピソード情報を処理するプログラムの内部では、この「キーワード」フィルターは読み取られないため、結果としてフィルターは一切適用されないまま、全てのエピソード情報が取得されてしまう。しかし、この実行ではエラーメッセージも警告メッセージも一切表示されず、あたかもフィルターが正常に機能し、多くのエピソードが該当したかのように見える。取得されたデータの件数も通常通りで、ログを見ても何も問題があったようには見えないのだ。
この「黙って無視される」状態は、システムにとって非常に危険な失敗モードである。特に、取得したデータ量に応じて料金が発生する「ペイ・パー・リザルト」方式のシステムでは深刻な問題だ。顧客は「AI」というキーワードでエピソードが絞り込まれることを期待してフィルターを設定したが、実際にはすべてのエピソードが取得され、その全量に対して課金されてしまう。顧客からすれば、「フィルターが機能して何もマッチしなかった」のか、「フィルターがそもそも実行されなかった」のかを区別する手段がない。どちらの場合も、取得されるデータが少ない、あるいは全くないように見えるかもしれないが、後者の場合は意図しない結果と無駄なコストを招く。顧客が求めていたものと実際に提供されたものが大きく異なっていても、システムからは何も知らされないのである。
このような状況は、実はプログラム内部の「既存の慣習の適用漏れ」によって生じることが多い。今回取り上げたプログラムにも、特定の入力が現在のモードで範囲外である場合に明示的に警告を出す機能が一部には既に実装されていた。例えば、チャート関連のフィルターがチャートモード以外で使われたり、特定のラベルがエピソードモード以外で使われたりした場合には、明確な警告メッセージがログに出力されるように設定されていた。しかし、レビュー情報とエピソード情報のフィルターに関する部分については、この警告メカニズムが適用されていなかったのだ。これは新しい機能の欠如ではなく、既に存在していた良い習慣が一部にしか適用されていなかったという「カバレッジギャップ」の問題だったのである。
この問題を解決するために行われた修正は、散発的なチェックを追加するのではなく、入力されたデータを解析した直後に、現在のモードと合わないフィルターが一括してチェックされるような処理を追加する、というものだった。具体的には、レビュー情報専用のフィルター(キーワード、最低評価、最高評価、並べ替え順)が現在のdataType(データ種類)が「レビュー」ではない場合に指定されていれば警告を出す。同様に、エピソード情報専用のフィルター(最低期間、明示的なコンテンツフィルター、最小リリース日、最大リリース日)が現在のdataTypeが「エピソード」でも「チャート」でもない場合に指定されていれば警告を出す、という仕組みを導入した。
この修正によって出力される警告メッセージは、非常に分かりやすく設計されている。無視されたフィルターのキー名を正確に列挙し、それらが本来どのdataTypeに適用されるべきであったかを明記する。さらに、その結果として「フィルターによって何も絞り込まれなかった」という明確な言葉で、技術者ではない顧客にも理解できるよう、具体的に何が起こったのかを伝える。これにより、フィルターが意図せず無視された場合でも、その事実と結果が明確にログに記録されるようになった。実際にテスト実行を行ったところ、レビューモードでエピソードモード用のフィルターを指定した場合、期待通りの警告メッセージが正確なフィールド名とともに表示されることが確認された。
このフィルター無視のバグと似ているが、実際には異なる状況も存在する。例えば、エピソード取得モードで「最低期間:7200秒」というフィルターを設定したのに、取得されたエピソードの中に期間情報がnull(不明)のものが含まれており、それらがフィルターで除外されなかったケースだ。これは一見すると、フィルターがサイレントに適用されなかったバグのように見えるかもしれない。しかし、実際にはApple自身のデータにおいて、約半分のエピソードが期間情報を持たない場合がある。このような状況で、期間情報がないエピソードを「短すぎる」と判断して除外してしまうと、実際には正しいエピソードが不当に破棄されてしまう。これは「サイレントにフィルターが適用されなかった」バグよりもさらに悪い結果を招く可能性がある。このプログラムでは、期間情報がないエピソードは意図的に保持され、その事実は事前に文書化されており、実行ログにも「〇件のエピソードは期間情報がなく、破棄されずに保持されました」という形で正確に報告される。つまり、これはフィルターが正しく機能して、あいまいなデータを破棄しないように意図的に設計された結果であり、フィルターが実行されなかったバグとは根本的に異なるのだ。
この経験から導かれる一般的な教訓は重要である。プログラムのスキーマ(設計図)上は有効な入力として認められているにもかかわらず、選択された動作モードにおいては意味をなさないフィルターキーは、スキーマ自体がそれを「正しい」と見なしてしまうため、厄介な存在となる。宣言されていない未知のキーは通常、エラーなしに無視されるか、実行前に検査ツールによって弾かれる。しかし、宣言されているがモードが異なるキーにはそのような安全ネットがない。スキーマが「問題ない」と言っても、それが実際に「使われた」ことを意味するわけではないのだ。
したがって、プログラムが現在の動作モードでは実行できないフィルターを受け取った場合、システムは必ずその旨を明示的に伝える必要がある。黙って無視することは許されない。なぜなら、その沈黙は顧客にとって「フィルターが実行されたが、すべてがマッチした(あるいは何もマッチしなかった)」という誤ったメッセージとして受け取られる可能性があるからだ。特に、結果に応じて課金される「ペイ・パー・リザルト」方式のシステムでは、このような偶発的な誤解は絶対に避けなければならない。
ちなみに、ClinicalTrials.govのようなシステムでは、フィルターセットにこのような落とし穴はない。そのシステムでは、どのフィルターも他の入力選択に関わらず常にアクティブであるため、フィルターが特定のモード外に陥るようなモード切り替えが存在しないからだ。このことからわかるのは、フィルターがあること自体がバグの原因なのではなく、複数の動作モードが存在し、そのモードによってフィルターの適用範囲が均一でない場合に、今回のような問題が発生するということである。