アダプティブセレクターは、わりと別のツールの手柄にされがちです。私が読んだスクレイパー比較記事の半分くらいは、「サイトをリデザインしても動く」といった機能を、実はそこまで対応していない大手のAIクローラーに結びつけています。この機能を前面に押し出しているPythonライブラリが Scrapling です。2026-07-09時点でGitHubスターは約68.7kと、かなり勢いよく注目を集めています。
そこで、こういう主張に対して本当に意味のあるテストを1つだけやってみました。テスト用ページを用意して、セレクターを保存したうえで、対象要素のクラス名を変えました。これは、サイトがリデザインされた翌朝にスクレイパーが静かに空振りしてしまう、まさにあの現象です。通常のセレクターでは結果は空でした。一方で、Scraplingのアダプティブマッチは同じ要素を見つけ出しました。ここまでは事実ですし、数値も出します。ただ、ほとんど誰も定量化していないのは「どこまで復元できて、どこで止まるのか」です。そして、その境界こそが今回のレビューの肝でした。
Scraplingは実際に何をするのか

Scraplingは、自分たちを「単一リクエストから大規模クロールまで扱えるアダプティブなWebスクレイピングフレームワーク」と説明しています。要するに、中身は2層構造です。ページを取得するHTTP Fetcher と、lxmlベースで解析を行う Selector があり、CSS/XPathに加えて ::text や ::attr() のような便利な疑似セレクターも使えます。ライセンスはBSD-3-Clauseで、オープンソースとしてはかなり使いやすい部類です。私は当時の最新版だった0.4.10を検証しました。古い版をベンチマークしたわけではないので、その点の心配は不要です。
その上に乗っているアダプティブ機能こそが、いちばん面白いところです。通常のセレクターを思い浮かべてください。あれは固定住所みたいなものです。「product-name クラスの要素を取る」と指定したら、建物番号、つまりクラス名を変えた瞬間に、その住所は空き地を指すことになります。Scraplingは、ある実行時に要素の指紋を保存し、次回以降にマークアップが変わっていても、その古い住所ではなく指紋を頼りに同じ要素を探し直せます。Scraplingのアダプティブスクレイピングのドキュメントによると、照合時には要素のタグ、テキスト、属性、兄弟要素、位置をもとに類似度を評価します。モデルは介在せず、保存済みの構造との比較だけで動きます。
ここで経緯をはっきりさせておくのは大事です。なぜなら、この機能の見え方が変わるからです。アダプティブな復元は実在し、しかも文書化された機能です。私が見つけたわけではありません。ベンダーのドキュメントにはSQLiteへの保存と類似度ベースのマッチングの仕組みが明記されており、第三者による解説記事でも同じように紹介されています。いわゆる自己修復セレクターの考え方自体も、テスト自動化の世界ではScrapling以前からありました。Scraplingの独自性は、それをネイティブのライブラリ機能として出している点です。lxml、parsel、BeautifulSoup のような一般的なパーサーは静的なセレクターしか持っておらず、自動で要素を追い直すことはありません。つまりこれは、他に誰も持っていない機能というより、文書化された独自機能を私が再現して、負荷をかけて検証した、という位置づけです。
アダプティブ検証の詳細

設定はこんな感じです。テスト用のカタログを作り、product-name というクラスを持つ商品要素を追跡しました。その後、そのクラスを product-title に変えて、同じコードを再実行しました。通常の .product-name セレクターは 0 件でした。これは、そのクラスがもう存在しないので当然の空結果です。一方で、Scraplingのアダプティブ再マッチは、前回の版で保存していた指紋を使って追跡中の要素を復元しました。生の結果はベンチマーク用リポジトリの local_adaptive_selector.json にあります。


ここからが、多くのレビューが飛ばしている部分です。さらに一歩進めて、合成的な複数要素テストをやりました。追跡対象を1つではなく3つにしたのです。すると、Scraplingが復元したのは3つ全部ではなく、最初に保存した1つだけでした。これは失敗でもバグでもありません。ドキュメント上、auto-matchは要素追跡であり、保存した要素ごとに1つの指紋を扱う設計です。なので、デフォルト設定で1/3という結果は、機能が意図どおりに動いたことを意味します。ただし、正確に言うなら「リデザインされたページ全体を自動復元する」ではなく、「要素単位で堅牢に追跡する」です。auto-matchは、追跡対象として指定した要素を追い続けます。複数要素への耐性は、自分で調整する必要があります。
この違いは、見た目以上に重要です。「マークアップ変更に強い」というのは見出し向きです。一方で、「指紋を付けた1つの要素を、マークアップが変わっても追跡し続けられる。残りは自分で調整する」というのが、実際に買っている機能です。前者を期待するとがっかりしますが、後者を期待すれば、かなりきれいに仕事をしてくれます。
セットアップ:誰も教えてくれない手間
これは実際に時間を取られたので、先に共有しておきます。pip install scrapling で入るのはパーサーだけです。私が from scrapling.fetchers import Fetcher と書いた瞬間、足りない依存関係が次々と出てきました。最初に curl_cffi、次に playwright、そのあとに browserforge。1つ解決しては次が出る、という流れでした。
対処法は、追加依存を入れることです。pip install "scrapling[fetchers]" を使うか、scrapling install のCLIを実行してください。これでHTTP+ブラウザの取得スタックがまとめて入ります。そこまでやれば普通に動きました。ただ、「ベースインストールは問題なさそうに見えて、最初のfetchで爆発する」という流れは本当ですし、事前にはほとんど見えません。最初のコマンドから [fetchers] の追加と、その重い依存ツリーを想定しておけば、無駄な回り道は避けられます。
素のHTTP抽出でどこまで耐えたか
fetcherを入れた後は、通常の抽出は安定していました。再現率は完全に1.0です。
| テスト | 結果 |
|---|---|
| 静的カタログ + ページネーション | 商品12/12件 |
| 記事抽出 | タイトル + 段落3/3件 |
| 動的JSON API | 8/8件 |
| Books to Scrape(公開サイト) | 商品20件 |
| HTTP 500の処理 | ステータスを明示、クラッシュなし |
ここでは、lxmlベースである強みがよく出ています。CSSもXPathも期待どおりに動き、::text と ::attr() の疑似セレクターのおかげで、抽出コードが長大なネストだらけにならず、短く読みやすいまま保てます。500エラーの扱いも、地味ですがかなり大事です。Fetcherはスタックトレースを吐くのではなく、ステータスコードをそのまま返してくれました。これは、定期実行に載せられるスクレイパーと、ずっと見張っていないといけないスクレイパーの差です。詳細な数値は scrapling-test-summary.json にあります。
派手さはありません。ただ、ちゃんと動く。それだけで十分価値があります。
意図的に対応していないこと

HTTP Fetcher はJavaScriptを実行しません。JSで描画されるテスト用ページに向けたところ、結果は 0 件でした。公開されている Quotes to Scrape のJSページ でも同じく 0 件です。これは欠陥ではありません。HTTP FetcherはHTMLをダウンロードするだけで、ブラウザを動かしているわけではないので、クライアント側でレンダリングされたコンテンツは、見た目どおりにはそこに存在しないのです。Scraplingには、JSページ向けに別の DynamicFetcher(ブラウザ対応)が用意されています。今回はそれを検証していないので、性能については断言しません。ただし、HTTP経路をクライアントレンダリング型のアプリに向けて、内容が見えると期待しないでください。
また、検知回避を目的とした StealthyFetcher もあります。これはあくまでコンプライアンス上の論点として扱います。声高に機能を売りにするタイプのものではありません。どこで、どのようにスクレイピングすることが許されるかは、あなた自身と法的な立場次第です。このレビューは回避能力ではなく、抽出能力を検証したものです。私はそれを実行していませんし、評価対象にもしていません。
長所と短所
長所:
- 通常のセレクターでは0件になったクラス名変更後に、アダプティブセレクターが追跡済み要素を実際に復元した。これこそScraplingを使う理由。
- 静的ページ、記事、JSON APIで再現率1.0のHTTP抽出。
- lxmlベースのCSS/XPathが扱いやすく、
::text/::attr()の疑似セレクターも見やすい。 - HTTP 500を落とさず、ステータスをそのまま返す。
- 検証した版が最新リリースだったため、バージョン差によるズレがない。
- BSD-3-Clauseで、商用利用にも使いやすい。
短所:
- auto-matchはページ全体ではなく、保存した1要素を追跡する。3要素テストでは1つだけが復元された。主張の大きさはそれに合わせるべき。
pip install scraplingではパーサーしか入らず、fetcherには[fetchers]追加と重い依存チェーンが必要。私はそれで苦労した。- HTTP FetcherはJavaScriptを実行しない。クライアント側コンテンツにはブラウザ対応の
DynamicFetcherが必要だが、今回は未検証。 - 売りの復元機能も、複数要素のケースでは手動調整が必要。
どんな人に向いているか、どんな人は避けるべきか
Scraplingが真価を発揮するのは、頻繁にUIを変えるサイトのスクレイパーを保守していて、クラス名1つの変更で抽出が翌朝ひっそり壊れる状況にうんざりしている人です。「セレクターが数週間おきに壊れる。とにかく欲しい1要素だけは見つけ続けてほしい」という悩みがあるなら、まさにそのためのツールです。アダプティブ層を使わなくても、静的ページやJSON API向けの軽量なlxml抽出器として十分に使えます。
ただし、次の2つのケースでは期待値を見直すか、別の選択肢を検討してください。まず、アダプティブセレクターがページ全体を自動修復してくれると思っているなら、それは誤解です。追跡するのは要素であって、レイアウトを再構築するわけではありません。次に、JavaScript主体の対象で、ブラウザ対応の DynamicFetcher を使いたくないなら、HTTP経路だけでは足りません。どちらにせよ、導入するなら最初のコマンドから [fetchers] 追加を入れてください。
管理型AIスクレイピングAPIの立ち位置
Scraplingは、自分で動かし、自分で保守する無料のオープンソースライブラリです。コードも、依存関係も、調整も自分で持ちます。その代わり、リクエストごとの費用はかからず、すべてを社内で完結できます。これは十分に筋の通った選択肢で、多くのチームにとって最適解です。
考えるべきなのは、「耐障害性の責任を誰が持つのか」です。Scraplingの答えは、あなたが持つ、です。要素に指紋を付け、追跡を調整します。管理型のAIスクレイピングAPIは、そこを別の形で解決します。変化への対応をサーバー側に移すのです。技術チーム向けの Thunderbit の開発者向けスタックは、その役割を担います。POST /extract で、あなたが定義したJSON Schemaに基づく構造化JSONを返し、レンダリング、ボット対策、マークアップの変化はサーバー側で吸収します。renderMode フラグで、抽出前にどこまでページを実行するかを制御できます。さらに、AIエージェントやコーディングアシスタント向けのThunderbit MCPサーバーもあり、thunderbit_suggest_fields は無料で最初に走って、抽出計画を立てます。CLIは npx @thunderbit/thunderbit-cli から使え、ターミナル、スクリプト、CIで活用できます。3つの入口すべての裏側で、同じAIエンジンが動いています。
本当のトレードオフは、どちらが上かではなく、耐障害ロジックをどこに置きたいかです。Scraplingなら、それは自分のコードの中にあります。指紋もチューニングも自分持ちで、1回ごとのコストはゼロ。ただし、その保守も自分で引き受けます。管理型APIなら、変化への対応を任せる代わりに、リクエストごとに料金を払います。小規模で、自前運用が好きで、調整を自分で握りたいなら、Scraplingのコントロール性が合っています。100サイト規模に広げたい、各サイトでセレクター指紋の世話をしたくない、というなら、管理型のほうがその保守コストを消してくれます。
全体を見比べたいなら、オープンソースWebスクレイパーの総合ベンチマーク でScraplingを他ツールと同じ条件で比較していますし、Scrapyレビュー と Collyレビュー も、HTTPファーストのフレームワークを知るうえで参考になります。
結論
Scraplingを使うべきか? 答えはイエスです。とくに、オープンソースのPython抽出器を探していて、その目玉が「マークアップが変わっても追跡中の要素を見失いにくい」ことなら、なおさらです。ただし、その機能の形を正しく理解しておく必要があります。壊れたセレクターでは取れなかった要素を、実際に復元しました。普通のスクレイパーなら静かに失っていたデータを、クラス名変更のあとでも拾えたのです。素のHTTP抽出もきれいで、すべてのテスト対象で完全再現率でした。ライセンスは寛容で、私が試した版も最新でした。
ただし、主張を正しく捉えれば、満足できるはずです。要素は追跡しますが、ページ全体を自動再構築するわけではありません。3要素のテストでは1つだけが復元されました。最初から [fetchers] を入れないと、私がはまった依存関係の壁にぶつかります。そして、ページにJavaScriptが必要なら、それはHTTP Fetcherではなくブラウザ対応のfetcherの仕事です。その範囲内では、Scraplingは評判どおりのことをきちんとやってくれますし、Python系スクレイピングライブラリの中でも、みんなが言うだけで実際には載せていない機能を本当に備えている、数少ないツールです。
ThunderbitでWebデータ抽出を試す Get Started Free
よくある質問
Scraplingのアダプティブセレクターは本当にサイト改修後も使えますか?
検証では、追跡対象の要素に対するクラス名変更なら対応できました。product-name を product-title に変えたあと、通常のセレクターは0件でしたが、アダプティブ再マッチは追跡中の要素を復元しました。ただし、ページ全体を修復するのではなく、保存済み要素を追跡します。3要素の合成テストでは1つだけが復元されました。ページ全体の自動復元ではなく、堅牢な要素追跡として捉えてください。
pip install scrapling のあとにfetcherをimportすると失敗するのはなぜですか?
ベースインストールはパーサーだけだからです。scrapling.fetchers を import すると、curl_cffi、playwright、browserforge という不足依存が連鎖的に表面化します。pip install "scrapling[fetchers]" か scrapling install CLIを使えば、fetcher一式が入り、importできます。
ScraplingはJavaScriptで描画されるページをスクレイピングできますか?
HTTP Fetcher ではできません。JS用のテストページでも公開されている Quotes のJSページでも0件でした。ブラウザを動かさずHTMLだけを取るためです。Scraplingには別途ブラウザ対応の DynamicFetcher があり、そこがJSページ向けですが、今回は検証していないため性能は判断していません。
Scraplingは通常の抽出で高速かつ正確ですか? 検証では正確でした。静的カタログ、記事ページ、JSON APIで再現率1.0、しかもlxmlベースのCSS/XPathは扱いやすいです。HTTP 500でも落ちず、ステータスを返しました。アダプティブ層を使わなくても、静的コンテンツ向けの軽量な抽出器として十分使えます。
Scraplingは商用利用できますか? BSD-3-Clauseなので、かなり寛容で商用向きです。とはいえ、実装前には必ず repo で最新のライセンスを確認してください。


