動的ウェブサイトのスクレイピング

動的ウェブサイトは、初期ページロードの後にJavaScriptを使用してコンテンツを読み込みます。このガイドでは、FourAのbrowser endpointを使用してこれらのサイトからデータを収集する方法を説明します。

課題

JavaScriptを多用するウェブサイトに標準的なHTTP requestを送信すると、HTMLのシェルは取得できますが、実際のコンテンツは取得できません。必要なデータ(商品リスト、価格、検索結果など)は、ブラウザでページがレンダリングされた後にJavaScriptによって読み込まれます。

これは、React、Vue、Angular、Next.jsなどのモダンなフレームワークでますます一般的になっています。

解決策:browser request

FourAのbrowser endpoint(POST /api/browser/)は、以下の処理を行うChromeブラウザインスタンスでURLを開きます。

  1. ページを読み込む
  2. すべてのJavaScriptを実行する
  3. コンテンツがレンダリングされるのを待つ
  4. 完全にレンダリングされたHTMLを返す

ステップ 1:必要な情報の特定

requestを送信する前に、ブラウザでターゲットページにアクセスし、DevTools(F12)を使用して、コンテンツが読み込まれたことを確認できるテキストや要素を見つけます。例えば、以下のようなものです。

  • JSのレンダリング後に表示される商品名
  • レンダリングされたHTML内の product-grid のようなCSSクラス
  • データが読み込まれたときにのみ表示される「results」のようなテキスト文字列

ステップ 2:browser requestの送信

curl -X POST https://eu.api.foura.ai/api/browser/ \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/products",
    "timeout_ms": 15000,
    "checkText": "product-grid"
  }'

checkText オプションは、レンダリングされたページに文字列「product-grid」が表示されることを確認するようFourAに指示します。表示されないままタイムアウトに達した場合、requestは失敗し、コンテンツが読み込まれなかったことがわかります。

ステップ 3:HTMLのパース

responseの body フィールドには、完全にレンダリングされたHTMLが含まれています。お好みのライブラリでパースしてください。

Python(BeautifulSoup)

import requests
from bs4 import BeautifulSoup

resp = requests.post("https://eu.api.foura.ai/api/browser/", headers={
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json"
}, json={
    "url": "https://example.com/products",
    "timeout_ms": 15000,
    "checkText": "product-grid"
})

html = resp.json()["body"]
soup = BeautifulSoup(html, "html.parser")

for product in soup.select(".product-card"):
    name = product.select_one(".product-name").text.strip()
    price = product.select_one(".product-price").text.strip()
    print(f"{name}: {price}")

Node.js(cheerio)

import * as cheerio from 'cheerio';

const resp = await fetch('https://eu.api.foura.ai/api/browser/', {
  method: 'POST',
  headers: { 'X-API-Key': 'YOUR_API_KEY', 'Content-Type': 'application/json' },
  body: JSON.stringify({
    url: 'https://example.com/products',
    timeout_ms: 15000,
    checkText: 'product-grid'
  })
});

const { body: html } = await resp.json();
const $ = cheerio.load(html);

$('.product-card').each((i, el) => {
  console.log($(el).find('.product-name').text(), $(el).find('.product-price').text());
});

トラブルシューティング

コンテンツがまだ空ですか?

  • ページが実際にJavaScriptレンダリングを使用しているか確認します(「ソースの表示」とDevToolsを比較)
  • timeout_ms を増やす:一部のページは読み込みに時間がかかります
  • ページが認証やcookieを必要としているか確認します(cookies パラメータを使用)

CAPTCHAページが表示されますか?

  • 単一のHTTP requestの場合は、自動IPローテーションのためにproxy endpoint(POST /api/proxy/)に切り替えます。
  • browser requestにproxyローテーションを追加するには、proxy endpointでラップするのではなく、browser endpointの proxy パラメータを使用します。proxy endpointは単一のHTTP requestのみをラップし、browser requestはラップしません。
curl -X POST "https://eu.api.foura.ai/api/browser/" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com", "proxy": "http://proxy-url:port"}'

次のステップ

最終更新日: 2026年5月31日