最新の Web からデータをスクレイピングすることは、かくれんぼゲームのように感じることがよくあります。 10 年前はほとんどの情報が HTML で簡単に入手できましたが、現在では開発者はデータを非表示にして難読化し、JavaScript で動的にレンダリングすることを好みます。
これはスクレイパーにとって興味深い課題となります。生の HTML コンテンツの解析に頼ることはできなくなりましたが、大量のデータがまだページ内に存在しているため、どこを調べればよいのかを知る必要があるだけです。
この包括的なガイドでは、隠された Web データを抽出するために使用できるさまざまな方法、ツール、テクニックについて説明します。
隠された Web データとは何ですか?
非表示の Web データとは、ページの生の HTML ソースでは直接表示されないデータを指します。これも:
ページの読み込み後に JavaScript を介してデータが動的に読み込まれます。たとえば、
<div>
動的に作成された HTML 要素を挿入してタグを追加します。JavaScript 変数に格納されたデータと埋め込まれたオブジェクト
<script>
タグ。多くの場合、データセット全体を含む JSON オブジェクト。AJAX リクエストを介したユーザー アクションに応じて生成される HTML コンテンツ。たとえば、コメント スレッドの拡張や無限スクロールのページネーションなどです。
フロントエンドが機能するために使用される内部 API リクエスト データとメタデータ。たとえば、CSRF トークン、ユーザー情報、一時キャッシュなどです。
スクレーパーによるアクセスを阻止することを目的とした難読化および暗号化されたデータ。
共通のテーマは、このデータはサーバーから返された元の HTML では利用できず、ページ上で実行されている JavaScript によって後で生成されるということです。
最新の動的 Web サイトは、高速なフロントエンド エクスペリエンスを構築するためにこの技術に大きく依存しています。すべてのデータを非表示にし、必要に応じて小さな塊に分けて適切にレンダリングできます。
残念ながら、これはスクレイパーがそのデータを取得するためにもう少し努力する必要があることを意味します。それを効率的に行う方法をいくつか見てみましょう。
HTML 内の隠しデータを見つける
最初のステップは、必要なデータが実際にページ JavaScript のどこかに隠されているかどうかを確認することです。
簡単な確認方法は次のとおりです。
ブラウザにターゲット ページをロードし、スクレイピングする一意のデータ識別子を見つけます。たとえば、製品名や ID です。
ブラウザのJavaScriptを無効にしてページを再読み込みしてください。これは開発者ツールで実行できます。
一意の識別子が生の HTML ソース コードにまだ存在するかどうかを確認します。
データが消えた場合は、ページの読み込み時に JavaScript によって動的にレンダリングされている可能性が高くなります。
次に、HTML ソースを調べて、そのコンテンツがどこでどのように生成されているかを見つける必要があります。
タグからのデータの抽出
隠しデータが存在する最も一般的な場所の 1 つは内部です。 <script>
タグ。
これには、JSON オブジェクト、JavaScript 変数、データセット全体、またはページを操作するコードを指定できます。
例:
<html>
<body>
<div id="product"></div>
<script>
// product data as javascript object
var data = {
"product": {
"name": "Super Product",
"price": 99.99
}
}
// data rendered on page load
document.getElementById("product").innerHTML = data.product.name + ": £" + data.product.price;
</script>
</body>
</html>
ここでは、実際の製品データは という JavaScript オブジェクト変数に保存されています。 data
.
製品 <div>
最初は空で、ページの読み込み時に動的に設定されます。
したがって、このデータを抽出するには、まず関連するデータを見つける必要があります。 <script>
生の HTML のタグ。これは、BeautifulSoup や Parsel などの HTML 解析ライブラリを使用して実行できます。
# extract scripts from HTML with BeautifulSoup
from bs4 import BeautifulSoup
html = # page HTML
soup = BeautifulSoup(html, ‘html.parser‘)
scripts = soup.find_all(‘script‘)
次に、スクリプトのコンテンツから具体的にデータを抽出する必要があります。
方法 1: JSON としてロードする
データが有効な JSON オブジェクトの場合は、Python のメソッドを使用して直接ロードできます。 json
モジュール:
import json
# find script with data variable
script = soup.find(‘script‘, text=lambda t: ‘data =‘ in t)
# load json directly
data = json.loads(script.string)
print(data[‘product‘])
# {‘name‘: ‘Super Product‘, ‘price‘: 99.99}
これは、script タグで指定されている場合にうまく機能します。 type="application/json"
.
方法 2: 正規表現マッチング
より複雑なデータの場合は、生の JavaScript コードを自分で解析する必要があります。ここで正規表現が役に立ちます。
コードをスキャンして、データ オブジェクトなどのパターンに一致する部分を抽出できます。
import re
import json
script = soup.find(‘script‘, text=lambda t: ‘data =‘ in t)
# match the data object by surrounding syntax
match = re.search(r‘data = ({.+})‘, script.string)
# load matched json
data = json.loads(match.group(1))
print(data[‘product‘])
# {‘name‘: ‘Super Product‘, ‘price‘: 99.99}
重要なのは、コードの残りの部分から必要なデータセットを一意に識別する正規表現パターンを注意深く作成することです。
方法 3: JavaScript の解析
高度なスクレイピングの場合、変数、関数、オブジェクトを含む完全な JavaScript コードを解析することが必要になる場合があります。
これにより、元の構造とコンテキストを維持しながら、あらゆるデータを抽出できます。
次のようなライブラリを使用できます PyJavaScript & Js2Py Python で JavaScript を解釈します。
たとえば、PyJavascript の場合は次のようになります。
import javascript
script = soup.find(‘script‘, text=lambda t: ‘data =‘ in t)
# init JavaScript interpreter
js = javascript.Interpreter()
# run script to define data variable
js.execute(script.string)
# access parsed data object
print(js.context[‘data‘][‘product‘])
# {‘name‘: ‘Super Product‘, ‘price‘: 99.99}
これにより、必要なデータセットだけでなく、JavaScript 環境全体を利用できるようになります。
JavaScript からの API データのスクレイピング
API は、最新の Web サイトの動的な動作のほとんどを強化します。 JavaScript は、データのロード、フォームの送信、またはインタラクションのトリガーを要求します。
ページのコードを詳しく調べることで、これらの API エンドポイントを見つけて、データを抽出するリクエストを模倣することができます。
たとえば、次の単純なスクリプトは、 /api/products/123
終点:
async function loadProduct(){
let response = await fetch(‘/api/products/123‘);
let product = await response.json();
// render product data to page
document.getElementById("product").innerHTML = product.name;
}
loadProduct();
HTML 内でこのスクリプトを見つけたら、次のことが可能になります。
API URL を抽出します。
fetch()
コールAJAX リクエストとレスポンスの形式を分析する
Requests などのライブラリを使用して Python で API リクエストを直接レプリケートする
これにより、ブラウザー コードを実行せずに、JavaScript が依存する API からデータをスクレイピングできます。
JavaScript 変数内のデータの検索
ページ データは、通常、JavaScript 変数に直接保存されます。
例:
// javascript data
var products = [
{name: "Product 1", price: 19.99},
{name: "Product 2", price: 24.99}
];
function renderProducts(){
// loop through products and render HTML
}
ここでは、完全な製品リストが変数に保存されています。 products
.
これを抽出するには、まずターゲットのデータ構造に一致する変数名を見つける必要があります。同様の正規表現アプローチを使用できます。
import re
import json
# find products variable
script = soup.find(‘script‘, text=lambda t: ‘var products =‘ in t)
# match products json
match = re.search(r‘var products = ({.+});‘, script.string)
data = json.loads(match.group(1))
print(data)
# [{name: "Product 1", price: 19.99}, {name: "Product 2", price: 24.99}]
データ構造がより複雑な場合は、JavaScript 環境全体を解析してスコープ内の変数にアクセスできます。
AJAX 経由でロードされたコンテンツのスクレイピング
Web サイトでは、ページの読み込み後に AJAX 経由でコンテンツを動的に読み込むことがよくあります。
たとえば、コメント スレッドの拡張、無限スクロールのページネーションやタブなどです。
このコンテンツは最初の HTML には存在しませんが、必要に応じてサーバーから要求されます。
これらの AJAX スニペットは次の方法でスクレイパーできます。
ページ上のネットワーク リクエストを監視して AJAX URL を識別します。
AJAX リクエストを再構築し、Python コードから直接送信します。
HTML/JSON データを含む AJAX 応答を解析します。
たとえば、スクロール時にページ分割されたデータを読み込む次のスクリプトについて考えてみましょう。
// initially loaded page data
var results = [ /* initial page of data */];
// paginate on scroll
window.addEventListener(‘scroll‘, function() {
var page = results.length / 20 + 1;
// request next page
fetch(‘/data?page=‘ + page)
.then(res => res.json())
.then(data => {
results.push(...data);
// render new data
});
});
ここで、次のページをリクエストしていることがわかります。 /data
エンドポイントとコンテンツの追加 results
変数に保存します.
これらのリクエストを複製してデータを直接スクレイピングできるため、レンダリングされた HTML 全体を解析する必要がなくなります。
ヘッドレスブラウザでの JavaScript の実行
究極の動的コンテンツ スクレイピングを実現するには、完全なヘッドレス ブラウザを起動し、ページをロードして、JavaScript 環境に直接アクセスします。
これにより、コードの評価、動的コンテンツのロード、ライブ ページで利用可能なデータ、関数、または DOM 要素へのアクセスが可能になります。
Python で Playwright を使用した例を次に示します。
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto(‘https://targetpage.com‘)
# evaluate browser context to get data
data = page.evaluate(‘window.products‘)
browser.close()
print(data)
キーが使用しているのは、 page.evaluate()
ロードされたページのコンテキストでカスタム JavaScript コードを実行します。
これにより、非表示のデータをスクレイピングするための完全なアクセスが可能になります。
欠点は、フル ブラウザ インスタンスを起動する必要があることです。これは、直接 HTTP リクエストよりも時間がかかります。したがって、このメソッドは複雑なページでは慎重に使用する必要があります。
難読化および暗号化されたデータ
Web サイトでは、スクレイピングを防ぐために JavaScript を意図的に難読化することがよくあります。
いくつかの例は次のとおりです。
変数名と関数名を次のような意味のない文字に縮小します。
a
,b
,fn1()
データセットを複数の変数とスクリプトに分割する
人間が判読できないようにデータを暗号化/エンコードする
実行時に断片化されたデータを動的に組み立てる
パッキング、難読化、アンチデバッグ、VM 実行などのコード保護技術
これにより、JavaScript の解析が非常に難しくなる可能性があります。コードを少し変更すると、スクレイパーが簡単に壊れてしまう可能性があります。
高度に難読化されたページを処理するには、いくつかの方法があります。
難読化されたソースを直接分析するのではなく、Playwright や Puppeteer などのヘッドレス ブラウザを使用して、実行されたコードを読み込みます。
コードの実行をトレースして、ブラウザ開発者ツールの使用やブラウザ トラフィックのプロキシなど、データがどのように組み立てられるかを理解します。
実際のユーザーがページをどのように操作するかを分析してデータ ソースを特定します。
変数が難読化されている場合でも、製品名、価格、ID などの既知のデータ構造をパターン マッチして、関連するコード部分を見つけます。
暗号化の場合は、暗号化キーを見つけるか、復号化アルゴリズムのリバース エンジニアリングを試してください。
難読化の変更に適応するようにスクレーパーを進化させることで、時間の経過とともに復元力を構築できます。
プロキシを使用した隠し API のスクレイピング
隠し Web API は、アクセスを防ぐために、IP レート制限、キャプチャ、ボット検出などの高度なアンチスクレイピング技術を採用していることがよくあります。
ここで、プロキシがスクレイピングに非常に役立ちます。住宅用 IP を介してリクエストをルーティングすることで、多くの保護を回避し、API に大規模にアクセスできます。
プロキシを使用したスクレイピングに関するいくつかのヒント:
定期的なプロキシ ローテーションを使用して、特定の IP でブロックされるのを防ぎます
幅広い多様性を実現するために、地域または ISP に基づいてプロキシ ローテーションを有効にする
循環する何千もの固有の IP を提供するバックコネクト プロキシを使用する
実際のユーザーの動作を模倣するためにプロキシごとのリクエスト レートを制限する
プロキシ認証を使用して、匿名 IP だけでなく実際のデバイスになりすます
キャプチャ、ブロック ページ、429 などの一般的なブロックを監視し、処理します
適切なプロキシ設定を使用すると、実質的にあらゆるターゲット サイトまたは非表示の API にアクセスできます。
隠しデータのスクレイピング サービス
JavaScript でレンダリングされたデータを抽出することを目的としたマネージド スクレイピング サービスもあります。
これらは、ブラウザーの自動化、プロキシ管理、および JavaScript 実行機能を提供します。
いくつかの例は次のとおりです。
スクレイピングビー – ページ内の JS を評価できるブラウザーおよびプロキシ API。
スクレイパーAPI – 自動プロキシローテーションを備えたヘッドレスブラウザ API。
アピファイ – 大規模なブラウザ自動化のためのアクター ランタイム。
スクレイプオプス – JS抽出を備えたビジュアルブラウザ自動化ビルダー。
スクラップフライ – 何百万ものバックコネクト住宅用プロキシを備えたブロック不可能なスクレイピング API。
これらのサービスは、動的ページ レンダリングの複雑さをすべて処理し、非表示データのスクレイピングを簡単にします。
主要な取り組み
非表示の Web サイトデータをスクレイピングするための重要なポイントは次のとおりです。
JavaScript を使用しないページを検査して、データが動的に読み込まれていることを確認します
HTML からスクリプト、変数、JSON オブジェクトを抽出して解析します
AJAX リクエストを分析および複製して、非表示の API にアクセスします
重い JS サイトで必要な場合はプロキシとヘッドレス ブラウザを使用する
パターンマッチと難読化されたコードのリバースエンジニアリング
スクレイパーを適応させてボット対策保護を処理する
適切な技術を使用すれば、事実上あらゆる公開 Web サイトのデータを抽出できます。どこを見るべきかを知る必要があるだけです。