Insights·2026-07-22

Scraplingとは何か、なぜサイトが改装されてもスクレイパーが壊れないのか

ScraplingはPythonでWebデータを収集するオープンソースのフレームワークです(BSD-3ライセンス、GitHubスター7万)。最大の特徴は適応型セレクタです。普通のスクレイパーは「このクラス名を持つ要素を取れ」のようにページ上の位置を規則で指定してデータを抜くため、相手サイトが改装されてクラス名や構造が変わると規則がすべてずれ、空の値しか返りません。Scraplingは最初の収集時に要素の特徴を一緒に保存しておき、次の実行でadaptiveオプションを有効にすると、類似度アルゴリズムで移動した要素を再び探し出します。だからサイトが変わっても、人がセレクタを直し直す必要がありません。さらに、Cloudflareのようなアンチボットの回避、大規模な並行クローラ、Claude・Cursorに接続できる内蔵MCPサーバーまで、一つのライブラリに収まっています。

Webスクレイピングとセレクタとは何か

Webスクレイピングとは、本来なら人がブラウザで開いて見るWebページから、欲しい情報だけをプログラムが自動で抜き出すことです。ショップの価格を毎日記録する、レビューを集める、複数サイトのお知らせを一箇所にまとめる、といった作業がすべてこれに当たります。

中心となる道具はセレクタ(selector)です。Webページは見た目は文字と画像ですが、中を開くとHTMLというタグ構造でできています。セレクタは、その構造の中で「どこをつかむか」を指す住所のようなものです。たとえばCSSセレクタ .price は「priceというクラスが付いた要素をつかめ」という意味で、その要素のテキストを取れば価格が得られます。

つまりスクレイパーは二つの部分に分かれます。ページを取ってくること(fetch)と、取ってきたHTMLからセレクタで欲しい断片をつかみ出すこと(parse)です。Scraplingはこの両方を扱います。

なぜスクレイパーはサイト改装で壊れるのか

問題は、セレクタが相手サイトの今の構造に縛られていることです。私が .btn-primary をつかむよう書いたのに、サイトが改装でそのクラス名を .button-main に変えると、私のセレクタはもう存在しないものを指します。コードは一文字も変えていないのに、結果は空です。

これは稀な事故ではなく、常に起きることです。相手サイトが私のスクレイパーに配慮する理由はありません。マーケティング改装、A/Bテスト、フレームワーク交換などの理由で、クラス名や構造は頻繁に変わります。そのたびに人がサイトを開き直し、新しいクラス名を探し、セレクタを直して入れます。長く運用するチームが保守にかける時間の大半は、まさにここから生まれます。

だから「壊れないスクレイパー」は長らくほぼ不可能でした。根本的に他人の画面構造に依存するからです。Scraplingの適応型セレクタは、その依存を緩める方法です。

適応型セレクタはどう要素を探し直すのか

適応型(adaptive)セレクタの考え方は単純です。最初に要素をうまくつかめたとき、その要素の特徴を一緒に保存します。クラス名だけでなく、タグの種類、親・兄弟の関係、周囲のテキスト、画面上の位置といった複数の手がかりです。これらの特徴をauto_saveオプションで保存します。

次にサイトが変わって元のセレクタが失敗すると、adaptiveオプションを有効にした状態で、Scraplingはページ全体から保存した特徴に最も近い要素を類似度で探し出します。クラス名が一つ変わっても、残りの手がかりがあれば移動した要素を再びつかみます。人が新しいクラス名を探してコードを直す段階が消えます。

adaptive_selector.py
from scrapling.fetchers import StealthyFetcher

StealthyFetcher.adaptive = True

# 初回収集 — auto_save=True で要素の特徴を一緒に保存
page = StealthyFetcher.fetch('https://example.com')
products = page.css('.product', auto_save=True)

# 後日サイト構造が変わったあと — adaptive=True で移動した要素を探し直す
products = page.css('.product', adaptive=True)

インストールして、コードを書かずに試す

インストールはPythonのパッケージ管理ツールpipで行います。ターミナルで pip install scrapling の一行で、パーサーとHTTPリクエスト機能が入ります。ブラウザ自動化(動的サイト・アンチボット回避)まで使うなら、scrapling install で必要なブラウザも一緒に取得します。

ターミナル — インストール
pip install scrapling

# ブラウザ系機能(StealthyFetcher など)も使うとき
scrapling install
ターミナル — コードなしで抽出
# ページ本文をMarkdownで保存
scrapling extract get 'https://example.com' content.md

# 特定のCSSセレクタだけ、Chromeになりすまして
scrapling extract get 'https://example.com' content.txt --css-selector '.article' --impersonate 'chrome'

# Cloudflareが塞ぐページを回避して抽出
scrapling extract stealthy-fetch 'https://nopecha.com/demo/cloudflare' out.html --solve-cloudflare
quickstart.py — コードで使うとき
from scrapling.fetchers import Fetcher

page = Fetcher.get('https://quotes.toscrape.com/')
quotes = page.css('.quote .text::text').getall()
print(quotes)

適応型のほかに — アンチボット回避・大規模クローラ・MCP

Scraplingが一つのライブラリにまとめた残り三つも、実務では大きいです。第一に、StealthyFetcherはCloudflare Turnstileのようなアンチボット防御を標準で回避します。TLSフィンガープリントとヘッダーを本物のブラウザのように偽装し、必要ならsolve_cloudflareオプションでブロック画面を解いて通過します。以前は有料サービスを付けなければ越えられなかった壁が、ライブラリのオプション一つになりました。

第二に、大規模収集のためのSpiderフレームワークがあります。Scrapyのようにstart_urlsとparse関数でクローラを定義し、並行数の制御、プロキシの自動ローテーション、Ctrl+Cで止めてから続きを再開するpause・resume、結果をリアルタイムに流すstreamingまで備えます。同じ道具で、1サイト数ページから数百万ページのクロールまで広げられます。

第三に、AIと接続する内蔵MCPサーバーがあります。ScraplingをMCPでClaudeやCursorのようなAIツールに接続すると、AIがWebページを丸ごと飲み込む代わりに、Scraplingが必要な部分だけを先に抽出して渡します。その分AIが処理するトークンが減り、速度とコストが一緒に下がります。AXの観点で特に有用な点です。

使う前に — 合法と礼儀

道具が簡単になったからといって、どこでも収集してよいわけではありません。スクレイピングは対象サイトの利用規約、ログイン・有料の壁、個人情報、著作権の影響を受けます。Scraplingにはrobots.txtを尊重するオプション(robots_txt_obey)、リクエスト間に間隔を置く遅延、ドメインのブロックといった仕組みが入っています。有効にして使うことが、相手サーバーへの礼儀であり、リスク管理でもあります。

まとめると、Scraplingはスクレイピングを「一度書いて直し続ける仕事」から「一度書いて放っておく仕事」へ移そうとする試みです。適応型セレクタが保守を減らし、アンチボット回避が参入の壁を下げ、MCPがAIとの接続コストを下げます。収集を運用中、あるいは新たに導入しようとしているなら、一度目を通す価値のあるオープンソースです。