製品統合リソースドキュメント料金
今すぐ開始

© 2026 CapSolver. All rights reserved.

お問い合わせ

Slack: lola@capsolver.com

製品

  • reCAPTCHA v2
  • reCAPTCHA v3
  • Cloudflare Turnstile
  • Cloudflare Challenge
  • AWS WAF
  • ブラウザ拡張機能
  • その他多数のCAPTCHAタイプ

統合

  • Selenium
  • Playwright
  • Puppeteer
  • n8n
  • パートナー
  • すべての統合を表示

リソース

  • 紹介プログラム
  • ドキュメント
  • APIリファレンス
  • ブログ
  • よくある質問
  • 用語集
  • ステータス

法務

  • 利用規約
  • プライバシーポリシー
  • 返金ポリシー
  • 個人情報を販売しない
ブログ/All/ウェブスクレイピング用のスクレイパーの構築方法: n8nとCapSolverを使用して
Apr03, 2026

ウェブスクレイピング用のスクレイパーの構築方法: n8nとCapSolverを使用して

Sora Fujimoto

Sora Fujimoto

AI Solutions Architect

価格や製品データ、保護されたページのコンテンツをスクレイピングしたことがある人は、URLを読み込むことよりも難しいのは、サイトのキャプチャを解決し、そのサイトが期待するように解決されたトークンを送信し、保護された応答から正しいデータを抽出することであることをすでに知っているでしょう。

そのため、単純な「キャプチャを解決して終了」という例は、実際の自動化には十分ではありません。サイトによっては、トークンをヘッダー、フォームボディ、JSONペイロード、クエリ文字列、クッキー、または他のアプリケーション固有のフィールドに送信する必要があります。reCAPTCHA、Turnstile、または他のキャプチャチャレンジを使用する可能性もあります。そして、保護された応答が戻ってきた後でも、セレクターと出力ロジックが目的に合致している必要があります。

このガイドでは、n8n で**CapSolver** を使用してキャプチャ保護サイトのスクレイパーを構築する方法を学びます。メインのウォークスルーは、リポジトリのワークフロー Scraping — Price & Product Details — CapSolver + Schedule + Webhook に基づいていますが、同じテンプレートは以下に適応できます:

  • 価格や製品データのスクレイピング
  • 在庫や保護されたコンテンツの変化の確認
  • 自分のアカウントにログインする
  • 他のサービスからWebhook経由で固定ターゲットのスクレイピングをトリガーする

この記事は、所有、管理、またはテストが許可されているターゲットでの実用的で認証された自動化についてです。

重要: これらのワークフローは例であり、スタートアップテンプレートであり、万能の即席レシピではありません。各特定のサイトに合わせてキャプチャ設定、トークン送信方法、リクエストペイロード、ヘッダー、クッキー、抽出セレクター、出力ロジックを変更することを期待してください。


このガイドが構築する内容

この記事のメイン例は、固定ターゲットのスクレイパーのテンプレートで、現在2つのアクティベーションモードをサポートしています:

  • スケジュール: 6時間ごとに自動実行
  • Webhook: 必要に応じて同じ構成済みターゲットをトリガー

デフォルトのリポジトリテンプレートでは、このワークフローは:

  • reCAPTCHA v3を解決
  • 保護された製品ページを取得
  • トークンをx-recaptcha-tokenヘッダー経由で送信
  • priceとproductNameを抽出
  • 現在の値を$workflow.staticDataと比較
  • アラートペイロードまたは変更なしペイロードを返す

同じパターンは:

  • スクレイパー
  • 製品詳細スクレイパー
  • 在庫チェッカー
  • 自分のアカウントのログインフロー

として使用できます。


一般的な使用ケース

これらのリポジトリテンプレートはすべて、同じ再利用可能な骨格に従います:

トリガー -> キャプチャを解決 -> 保護されたリクエストを送信 -> 結果を抽出 -> 比較/保存/出力

この構造はいくつかの正当な使用ケースに適合します:

使用ケース 変更される内容
スクレイピング 価格フィールドを抽出し、時間とともに比較
製品データのスクレイピング タイトル、SKU、販売者、在庫、または説明などのフィールドを抽出
在庫チェック 利用可能テキスト、数量、または購入ボタンの状態を比較
自分のアカウントにログイン 解決されたトークンをログインリクエストに送信し、ログイン成功を確認
保護されたコンテンツの取得 ゲートされたコンテンツを取得し、抽出されたフィールドを返す
Webhookでトリガーされるスクレイピング 他のサービスが固定された構成済みターゲットを必要に応じてアクティブ化できるようにする

構造は再利用可能ですが、実際には各サイトで実装の詳細が異なります。実際には、ここにある各ワークフローを例として扱い、解決設定、リクエストの形、トークンの配置、抽出ロジックを自動化するターゲットに合わせて調整する必要があります。


ワークフロー: 使用ケースの例

上記のメインスクレイパーのワークフローは、生のページコンテンツを取得し、価格を比較します。以下のワークフローは、同じキャプチャ解決パターン - トリガー → キャプチャを解決 → 保護されたリクエストを送信 → 結果を評価 - を特定の使用ケースに拡張します。それぞれには同じ前提条件が必要です:n8nインスタンス、CapSolverの資格情報、およびターゲットのキャプチャパラメータ。

ワークフロー 目的
Scraping — Price & Product Details — CapSolver + Schedule + Webhook 固定ターゲットのスケジュール + Webhookテンプレートで、reCAPTCHA v3を解決し、x-recaptcha-tokenにトークンを送信し、priceとproductNameを抽出し、$workflow.staticDataと値を比較し、スクレイピング、製品詳細抽出、または同様の保護された製品ページのチェックに使用できます

アクティベーションの注意: このテンプレートはactive: falseとしてインポートされます。Webhookのパスは、プレースホルダーを構成し、CapSolverの資格情報を選択し、n8nでワークフローをアクティブ化するまで有効ではありません。


前提条件

開始する前に、以下のものを確認してください:

  1. n8nインスタンス
  2. APIキーと残高を持つCapSolverアカウント
  3. n8nで構成されたCapSolverノード
  4. ターゲットURLと抽出したいフィールド
  5. ターゲットで必要なキャプチャパラメータ
  6. ブラウザで保護されたリクエストが実際にどのように送信されるかの明確な理解

この記事のメイン例では、ターゲットがreCAPTCHAを使用していると仮定されているため、キー値は以下の通りです:

  • websiteURL
  • websiteKey
  • pageAction for reCAPTCHA v3

重要: 以下のパラメータの特定のウォークスルーはreCAPTCHAの例に限定されています。実際のターゲットは、Cloudflare Turnstile、Cloudflare Challenge、GeeTest、DataDome、AWS WAF、MTCaptchaなど、別のチャレンジタイプを使用する可能性があります。その場合、解決ノードの設定、必要なフィールド、および保護されたリクエストのパターンが異なります。


reCAPTCHAパラメータの特定方法

reCAPTCHA保護ページの場合、コア値は通常以下の通りです:

パラメータ 説明
websiteURL キャプチャが表示または必要なURL
websiteKey ページで使用される公開サイトキー
pageAction reCAPTCHA v3が期待するアクション文字列

リポジトリの価格モニターテンプレートでは、CapSolverノードは以下の通り構成されています:

  • operation: reCAPTCHA v3
  • websiteURL: https://YOUR-TARGET-SITE.com/product-page
  • websiteKey: YOUR_SITE_KEY_HERE
  • pageAction: view_product

reCAPTCHAターゲットを検証する際には、以下のことを確認してください:

  • どのreCAPTCHAバージョンを使用しているか
  • pageActionが必要かどうか
  • 解決されたトークンが実際に送信される場所

重要: これは万能のキャプチャ検出セクションではありません。ターゲットが別のチャレンジタイプを使用している場合(例:Cloudflare Turnstile、Cloudflare Challenge、GeeTest、DataDome、AWS WAF、MTCaptcha)では、CapSolverの設定と解決されたトークンを送信するHTTPリクエストを変更する必要があります。


メインワークフロー: Scraping — Price & Product Details — CapSolver + Schedule + Webhook

リポジトリのワークフロー Scraping — Price & Product Details — CapSolver + Schedule + Webhook は、2つの固定ターゲットのアクティベーションパスをサポートしています:

  • 定期的なチェック用の Every 6 Hours
  • 必要に応じて実行する Webhook Trigger

両方のパスは同じターゲットプレースホルダーと同じスクレイパー論理を使用します。Webhookバージョンは単に**Respond to Webhook**で終わるため、呼び出し元が最終的なアラートまたは変更なしペイロードをJSONとして受け取れます。

スケジュールパス

スケジュールパスには以下のノードが使用されます:

  1. Every 6 Hours
  2. Solve reCAPTCHA v3
  3. Fetch Product Page
  4. Extract Data
  5. Compare Data
  6. Data Changed?
  7. Build Alert
  8. No Change

Webhookパス

Webhookパスは同じ論理で同じ固定ターゲットを処理します:

  1. Webhook Trigger
  2. Solve reCAPTCHA v3 [Webhook]
  3. Fetch Product Page [Webhook]
  4. Extract Data [Webhook]
  5. Compare Data [Webhook]
  6. Data Changed? [Webhook]
  7. Build Alert [Webhook]
  8. No Change [Webhook]
  9. Respond to Webhook

メインロジックの動作方法

1. トリガー

定期的なチェック(例:スクレイピングや在庫チェック)が必要な場合はスケジュールを使用します。

他のワークフロー、サービス、またはアプリケーションが同じ構成済みターゲットを必要に応じてアクティブ化する必要がある場合はWebhookを使用します。

2. reCAPTCHA v3を解決

テンプレートは以下の設定を使用します:

設定 値
Operation reCAPTCHA v3
websiteURL https://YOUR-TARGET-SITE.com/product-page
websiteKey YOUR_SITE_KEY_HERE
pageAction view_product

3. 保護されたページを取得

解決されたトークンはリクエストヘッダーに送信されます:

ヘッダー 値
user-agent ブラウザスタイルのユーザーエージェント
x-recaptcha-token {{ $json.data.solution.gRecaptchaResponse }}

これはワークフローで最も重要な詳細の1つです。リポジトリのテンプレートはトークンが常にg-recaptcha-responseに属するとは仮定していません。この例では、カスタムヘッダーに送信されます。

4. priceとproductNameを抽出

HTMLノードは以下の通り抽出します:

キー CSSセレクター
price .product-price, [data-price], .price
productName h1, .product-title

5. 以前の実行と比較

Codeノードは以下の値を使用して保存と比較を行います:

  • $workflow.staticData.lastPrice
  • $workflow.staticData.lastChecked

これにより、ワークフローは以下の違いを判別できます:

  • 最初のチェック
  • 変更なし
  • 価格の上昇
  • 価格の下落

6. アラートまたは変更なしに分岐

IFノードは{{ $json.changed }}をチェックします。

価格が変更された場合、ワークフローは**Build Alert**に進みます。

そうでない場合、**No Change**に進みます。

Webhookパスでは、どちらの分岐も**Respond to Webhook**に進みます。


なぜこれが本当にスクレイパーのテンプレートなのか

メインの例には価格比較ロジックが含まれていますが、これは保護された製品ページのスクレイパーのテンプレートに比較ロジックを組み込んだものと考えるのがより有用です。

再利用可能な部分は:

  • トリガーのモード
  • キャプチャの種類
  • 解決設定
  • 保護されたリクエスト
  • 抽出セレクター
  • 比較または出力ロジック

これがなぜ同じ構造が:

  • スクレイピング
  • 製品詳細抽出
  • 在庫チェック
  • 保護されたページの検証
  • 自分のアカウントのログインチェック

をサポートできるのかの理由です。


おそらく変更が必要な点

これは実際のターゲットで最も重要な部分です。

ほとんどの実際のサイトでは、ここにあるほぼすべての内容を調整する必要があります:チャレンジタイプ、解決パラメータ、トークンが送信される場所、リクエストボディ、クッキー、ヘッダー、セレクター、および最終的な成功基準。これらのリポジトリワークフローは、動作可能なパターンの例であり、すべてのサイトにそのまま適合する固定レシピではありません。

1. トリガーのモード

リポジトリの使用ケースワークフローは現在スケジュール + Webhookをサポートしています。

使用するには:

  • スケジュール:定期的なチェックに使用
  • Webhook:他のサービスから必要に応じてアクティブ化

これらのテンプレートのWebhookパスは固定ターゲットアクティベーターであり、任意のユーザー提供ターゲットの公開APIではありません。

2. CAPTCHAの種類

メインの価格モニターアイテムはreCAPTCHA v3を使用していますが、ターゲットは次のいずれかを使用する可能性があります:

  • reCAPTCHA v2
  • reCAPTCHA v3
  • Cloudflare Turnstile
  • Cloudflare Challenge
  • GeeTest V3 / V4
  • DataDome
  • AWS WAF
  • MTCaptcha
  • 他のサポートされているチャレンジタイプ

これにより、解決ステップをそれに応じて更新する必要があります。

3. CAPTCHA解決設定

2つのサイトがともにreCAPTCHAを使用していても、設定は異なる場合があります。

変更が必要な可能性があるのは:

  • CapSolverのoperationまたはタスクタイプ
  • websiteURL
  • websiteKey
  • pageAction
  • 非表示/エンタープライズ関連のオプション
  • その他のサイト固有のチャレンジ設定

スクレイパーのテンプレートは、これらが変更される予定であるため、プレースホルダー構成フィールドとして公開しています。

4. トークンが送信される場所

トークンが常に同じ場所に送信されるとは考えないでください。

このリポジトリではいくつかのパターンがすでに示されています:

パターン リポジトリの例
リクエストヘッダー Scraping — CapSolver + Schedule は x-recaptcha-token を使用
フォームボディ ログインワークフローは通常フォームエンコードされたボディの g-recaptcha-response を使用

実際のサイトでは、解決されたトークンは:

  • ヘッダー
  • フォームフィールド
  • JSONペイロード
  • クエリパラメータ
  • クッキー
  • 隠しフィールド
  • 他のアプリケーション固有の値

に属する可能性があります。

このリポジトリの例は1つの送信パターンであり、万能ではありません。

5. 保護されたリクエストそのもの

保護されたリクエストにはキャプチャやチャレンジトークンだけでなく、他のものが必要な場合があります。

調整が必要なのは:

  • ヘッダー
  • クッキー
  • CSRF値
  • 隠しフィールド
  • フォームエンコード
  • JSONボディの形状
  • リクエスト方法

これは特に:

  • ログインフロー
  • ゲートされたフォーム送信やチェックアウト

で一般的です。

6. 抽出する内容

メインのスクレイパーのテンプレートは:

  • price
  • productName

を抽出しますが、以下に置き換えることができます:

  • タイトル
  • 在庫状況
  • SKU
  • 説明
  • バリアント値
  • 利用可能テキスト
  • 完全な保護されたコンテンツブロック

7. 比較または出力する内容

現在の価格モニターコードは数値値を比較していますが、同じパターンは以下に適応できます:

  • 価格変更
  • 在庫変更
  • ログイン成功
  • 登録成功
  • コンテンツ差分
  • サイトの健全状態
  • 比較なしの生データエクスポート

このワークフローをインポートする

以下のJSONは、このリポジトリから**Scraping — Price & Product Details — CapSolver + Schedule + Webhook**の現在のインポート可能なバージョンであり、スケジュール + Webhookのアクティベーションパスを含んでいます。

クリックしてワークフローのJSONを展開
json Copy
{
  "nodes": [
    {
      "parameters": {
        "content": "## Scraping \u2014 Price & Product Monitor\n\n### How it works\n\n1. Triggers either by schedule or webhook input to start price monitoring.\n2. Solves reCAPTCHA to access the targeted product page.\n3. Retrieves and extracts data from the product page for further analysis.\n4. Compares newly fetched data with previously stored data to detect changes.\n5. Determines if changes occurred and prepares alerts if needed.\n6. Sends responses based on data analysis through designated channels.\n\n### Setup steps\n\n- [ ] Configure scheduled trigger interval in 'Every 6 Hours' node.\n- [ ] Set target website details in 'Set Target Config [Schedule]'.\n- [ ] Configure reCAPTCHA solver with API key in 'Solve reCAPTCHA v3' nodes.\n- [ ] Set up Webhook URL and path in 'Webhook Trigger'.\n- [ ] Define alert criteria and destination in 'Build Alert' nodes.\n\n### Customization\n\nAdjust the extraction pattern in 'Extract Data' nodes to fit specific product details.",
        "height": 896,
        "width": 480
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -1328,
        -304
      ],
      "id": "52c7808e-d2bc-4779-85e6-909a51066338",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "content": "## Scheduled trigger setup\n\nInitializes the data monitoring process every 6 hours using a schedule trigger and sets the target configuration for scraping.",
        "height": 320,
        "width": 496,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -752,
        -160
      ],
      "id": "3c5cee67-552d-48ea-8717-7c5126269e2e",
      "name": "Sticky Note1"
    },
    {
      "parameters": {
"content": "## スケジュールされたスクリーニングプロセス\n\nスケジュールされたトリガーに従って、reCAPTCHAを解決し、製品ページを取得し、データを抽出して以前の記録と比較して変更を識別します。",
        "height": 496,
        "width": 1680,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -144,
        -304
      ],
      "id": "d0315be2-111c-4893-bf42-2f2cc2eb186f",
      "name": "Sticky Note2"
    },
    {
      "parameters": {
        "content": "## Webhookトリガーのセットアップ\n\nインバウンドWebhook経由で手動でトリガーされるデータモニタリングを処理し、進むためにreCAPTCHAを解決します。",
        "height": 304,
        "width": 816,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -768,
        336
      ],
      "id": "a78f1606-07fb-40fd-af82-e1dc9b766206",
      "name": "Sticky Note3"
    },
    {
      "parameters": {
        "content": "## Webhookスクリーニングプロセス\n\nWebhookトリガーされたリクエストを処理し、製品ページを取得し、データを抽出し、変更を判断します。",
        "height": 272,
        "width": 1088,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        160,
        320
      ],
      "id": "1a677fd9-a3a8-404f-ba9a-2b087d7bfe11",
      "name": "Sticky Note4"
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 6
            }
          ]
        }
      },
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.3,
      "position": [
        -704,
        0
      ],
      "id": "sc-901",
      "name": "6時間ごと"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "cfg-001",
              "name": "websiteURL",
              "value": "https://YOUR-TARGET-SITE.com/product-page",
              "type": "string"
            },
            {
              "id": "cfg-002",
              "name": "websiteKey",
              "value": "YOUR_SITE_KEY_HERE",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -400,
        0
      ],
      "id": "sc-900",
      "name": "Set Target Config [Schedule]"
    },
    {
      "parameters": {
        "operation": "reCAPTCHA v3",
        "websiteURL": "={{ $json.websiteURL }}",
        "websiteKey": "={{ $json.websiteKey }}",
        "optional": {
          "pageAction": "view_product"
        }
      },
      "type": "n8n-nodes-capsolver.capSolver",
      "typeVersion": 1,
      "position": [
        -96,
        0
      ],
      "id": "sc-902",
      "name": "Solve reCAPTCHA v3",
      "credentials": {
        "capSolverApi": {
          "id": "BeBFMAsySMsMGeE9",
          "name": "CapSolver account"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $('Set Target Config [Schedule]').first().json.websiteURL }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "user-agent",
              "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
            },
            {
              "name": "x-recaptcha-token",
              "value": "={{ $json.data.solution.gRecaptchaResponse }}"
            }
          ]
        },
        "options": {
          "response": {
            "response": {}
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        208,
        0
      ],
      "id": "sc-903",
      "name": "Fetch Product Page"
    },
    {
      "parameters": {
        "operation": "extractHtmlContent",
        "extractionValues": {
          "values": [
            {
              "key": "price",
              "cssSelector": ".product-price, [data-price], .price"
            },
            {
              "key": "productName",
              "cssSelector": "h1, .product-title"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.html",
      "typeVersion": 1.2,
      "position": [
        512,
        0
      ],
      "id": "sc-904",
      "name": "Extract Data"
    },
    {
      "parameters": {
        "jsCode": "const staticData = $workflow.staticData;\nconst currentPrice = $input.first().json.price;\nconst previousPrice = staticData.lastPrice;\nconst productName = $input.first().json.productName || 'Product';\nconst parsePrice = (str) => { if (!str) return null; const match = str.match(/[\\d,]+\\.?\\d*/); return match ? parseFloat(match[0].replace(',', '')) : null; };\nconst currentNum = parsePrice(currentPrice);\nconst previousNum = parsePrice(previousPrice);\nstaticData.lastPrice = currentPrice;\nstaticData.lastChecked = new Date().toISOString();\nconst changed = previousNum !== null && currentNum !== null && currentNum !== previousNum;\nconst direction = changed ? (currentNum < previousNum ? 'dropped' : 'increased') : 'unchanged';\nconst diff = changed ? Math.abs(currentNum - previousNum).toFixed(2) : '0';\nreturn [{ json: { productName, currentPrice, previousPrice: previousPrice || 'first check', changed, direction, diff: changed ? `$${diff}` : null, checkedAt: new Date().toISOString() } }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        800,
        0
      ],
      "id": "sc-905",
      "name": "Compare Data"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "if-1",
              "leftValue": "={{ $json.changed }}",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1104,
        0
      ],
      "id": "sc-906",
      "name": "Data Changed?"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "a1",
              "name": "alert",
              "value": "=Price {{ $json.direction }} for {{ $json.productName }}: {{ $json.previousPrice }} \u2192 {{ $json.currentPrice }}",
              "type": "string"
            },
            {
              "id": "a2",
              "name": "severity",
              "value": "={{ $json.direction === 'dropped' ? 'deal' : 'info' }}",
              "type": "string"
            },
            {
              "id": "a3",
              "name": "checkedAt",
              "value": "={{ $json.checkedAt }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1392,
        -192
      ],
      "id": "sc-907",
      "name": "Build Alert"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "n1",
              "name": "status",
              "value": "no_change",
              "type": "string"
            },
            {
              "id": "n2",
              "name": "currentPrice",
              "value": "={{ $json.currentPrice }}",
              "type": "string"
            },
            {
              "id": "n3",
              "name": "checkedAt",
              "value": "={{ $json.checkedAt }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1392,
        32
      ],
      "id": "sc-908",
      "name": "No Change"
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "price-monitor",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        -720,
        464
      ],
      "id": "sc-909",
      "name": "Webhook Trigger",
      "webhookId": "sc-909-webhook",
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "operation": "reCAPTCHA v3",
        "websiteURL": "={{ $json.body.websiteURL }}",
        "websiteKey": "={{ $json.body.websiteKey }}",
        "optional": {
          "pageAction": "={{ $json.body.pageAction || 'view_product' }}"
        }
      },
      "type": "n8n-nodes-capsolver.capSolver",
      "typeVersion": 1,
      "position": [
        -96,
        464
      ],
      "id": "sc-910",
      "name": "Solve reCAPTCHA v3 [Webhook]",
      "credentials": {
        "capSolverApi": {
          "id": "BeBFMAsySMsMGeE9",
          "name": "CapSolver account"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $('Webhook Trigger').item.json.body.websiteURL }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "user-agent",
              "value": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"
            },
            {
              "name": "x-recaptcha-token",
              "value": "={{ $json.data.solution.gRecaptchaResponse }}"
            }
          ]
        },
        "options": {
          "response": {
            "response": {}
          }
        }
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        208,
        432
      ],
      "id": "sc-911",
      "name": "Fetch Product Page [Webhook]"
    },
    {
      "parameters": {
        "operation": "extractHtmlContent",
        "extractionValues": {
          "values": [
            {
              "key": "price",
              "cssSelector": ".product-price, [data-price], .price"
            },
            {
              "key": "productName",
              "cssSelector": "h1, .product-title"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.html",
      "typeVersion": 1.2,
      "position": [
        512,
        432
      ],
      "id": "sc-912",
      "name": "Extract Data [Webhook]"
    },
    {
      "parameters": {
        "jsCode": "const staticData = $workflow.staticData;\nconst currentPrice = $input.first().json.price;\nconst previousPrice = staticData.lastPrice;\nconst productName = $input.first().json.productName || 'Product';\nconst parsePrice = (str) => { if (!str) return null; const match = str.match(/[\\d,]+\\.?\\d*/); return match ? parseFloat(match[0].replace(',', '')) : null; };\nconst currentNum = parsePrice(currentPrice);\nconst previousNum = parsePrice(previousPrice);\nstaticData.lastPrice = currentPrice;\nstaticData.lastChecked = new Date().toISOString();\nconst changed = previousNum !== null && currentNum !== null && currentNum !== previousNum;\nconst direction = changed ? (currentNum < previousNum ? 'dropped' : 'increased') : 'unchanged';\nconst diff = changed ? Math.abs(currentNum - previousNum).toFixed(2) : '0';\nreturn [{ json: { productName, currentPrice, previousPrice: previousPrice || 'first check', changed, direction, diff: changed ? `$${diff}` : null, checkedAt: new Date().toISOString() } }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        800,
        432
      ],
      "id": "sc-913",
      "name": "Compare Data [Webhook]"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "if-2",
              "leftValue": "={{ $json.changed }}",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1104,
        432
      ],
      "id": "sc-914",
      "name": "Data Changed? [Webhook]"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "a4",
              "name": "alert",
              "value": "=Price {{ $json.direction }} for {{ $json.productName }}: {{ $json.previousPrice }} \u2192 {{ $json.currentPrice }}",
              "type": "string"
            },
            {
              "id": "a5",
              "name": "severity",
              "value": "={{ $json.direction === 'dropped' ? 'deal' : 'info' }}",
              "type": "string"
            },
            {
              "id": "a6",
              "name": "checkedAt",
              "value": "={{ $json.checkedAt }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1424,
        384
      ],
      "id": "sc-915",
      "name": "Build Alert [Webhook]"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "n4",
              "name": "status",
              "value": "no_change",
              "type": "string"
            },
            {
              "id": "n5",
              "name": "currentPrice",
              "value": "={{ $json.currentPrice }}",
              "type": "string"
            },
            {
              "id": "n6",
              "name": "checkedAt",
              "value": "={{ $json.checkedAt }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1440,
        592
      ],
      "id": "sc-916",
      "name": "No Change [Webhook]"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify($json) }}",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        1712,
        512
      ],
      "id": "sc-917",
      "name": "Respond to Webhook"
    }
  ],
  "connections": {
    "6時間ごと": {
      "main": [
        [
          {
"node": "ターゲット設定のスケジュールを設定",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ターゲット設定のスケジュールを設定": {
      "main": [
        [
          {
            "node": "reCAPTCHA v3を解決",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "reCAPTCHA v3を解決": {
      "main": [
        [
          {
            "node": "製品ページを取得",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "製品ページを取得": {
      "main": [
        [
          {
            "node": "データを抽出",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "データを抽出": {
      "main": [
        [
          {
            "node": "データを比較",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "データを比較": {
      "main": [
        [
          {
            "node": "データが変更されましたか?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "データが変更されましたか?": {
      "main": [
        [
          {
            "node": "アラートを構築",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "変更なし",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhookトリガー": {
      "main": [
        [
          {
            "node": "reCAPTCHA v3 [Webhook]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "reCAPTCHA v3 [Webhook]": {
      "main": [
        [
          {
            "node": "製品ページを取得 [Webhook]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "製品ページを取得 [Webhook]": {
      "main": [
        [
          {
            "node": "データを抽出 [Webhook]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "データを抽出 [Webhook]": {
      "main": [
        [
          {
            "node": "データを比較 [Webhook]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "データを比較 [Webhook]": {
      "main": [
        [
          {
            "node": "データが変更されましたか? [Webhook]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "データが変更されましたか? [Webhook]": {
      "main": [
        [
          {
            "node": "アラートを構築 [Webhook]",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "変更なし [Webhook]",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "アラートを構築 [Webhook]": {
      "main": [
        [
          {
            "node": "Webhookに応答",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "変更なし [Webhook]": {
      "main": [
        [
          {
            "node": "Webhookに応答",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "meta": {
    "instanceId": "962ff0267b713be0344b866fa54daae28de8ed2144e2e6867da355dae193ea1f"
  }
}

テストする

プレースホルダーを構成し、ワークフローを有効にした後、Webhookのパスをトリガーしてください:

bash Copy
curl -X POST https://your-n8n-instance.com/webhook/price-monitor \
  -H "Content-Type: application/json" \
  -d '{}'

期待される応答(最初のチェック):

json Copy
{
  "status": "no_change",
  "currentPrice": "$29.99",
  "checkedAt": "2026-03-11T08:00:00.000Z"
}

期待される応答(価格が変更された場合):

json Copy
{
  "alert": "Widget Proの価格が下がりました: $39.99 → $29.99 (-$10.00)",
  "severity": "deal",
  "checkedAt": "2026-03-11T14:00:00.000Z"
}

実際の価格データが含まれた応答は、パイプライン全体が動作したことを確認します — CAPTCHAが解決され、保護されたページが取得され、データが抽出され、比較ロジックが実行されました。


問題解決

トークンが解決されたが、依然としてブロックされている

CapSolverがトークンを返すが、サイトが依然としてリクエストをブロックしている場合、問題は解決自体にあるとは限りません。一般的な原因は次の通りです:

  • 間違ったCAPTCHAタイプ
  • 間違った解決設定
  • 間違ったpageAction
  • トークンが間違った場所に送信されている
  • コokies、ヘッダー、または隠しフィールドが不足している

サイトが別のチャレンジタイプを使用している

ターゲットがreCAPTCHA以外のチャレンジ — 例えばCloudflare Turnstile、Cloudflare Challenge、GeeTest、DataDome、AWS WAF、またはMTCaptcha — を使用している場合、メインの例は変更せずに動作しません。次を更新する必要があります:

  • CapSolverノードの構成
  • 期待されるチャレンジパラメータ
  • トークンを送信する保護されたリクエスト

セレクターが何も返さない

HTMLノードが予期したフィールドを抽出しない場合:

  • 実際に保護されたページが受け取れているか確認してください
  • 返されたHTMLに対してセレクターを確認してください
  • データがクライアントサイドレンダリングのみで存在しているか確認してください

Webhookが動作しない

リポジトリのテンプレートは非アクティブでインポートされます。以下の手順を完了するまで:

  1. プレースホルダーを構成する
  2. 資格情報を選択する
  3. ワークフローを有効にする

Webhookのパスは有効になりません。


最適な実践方法

  1. トークンを解決した後すぐに使用してください。
  2. n8nにコピーする前に、正確なブラウザリクエストを確認してください。
  3. すべてのターゲットが異なる解決設定を必要とする可能性があると仮定してください。
  4. すべてのターゲットが異なる送信ロジックを必要とする可能性があると仮定してください。
  5. デバッグを開始する前に保護された応答を確認してください。
  6. リポジトリのテンプレートを万能のインストールではなく、スタートアップとして扱ってください。
  7. Webhookテンプレートを固定ターゲットに保ち、それ以外の公開の理由がない限り、公開しないでください。
  8. 解決 -> 送信 -> 抽出のサイクルをテストしてください。解決ステップのみをテストしないでください。
  9. Build Alertまたは認証成功/失敗ノードの後に、下流の通知またはストレージノードを追加してください。

開始する準備はできましたか? CapSolverに登録し、初回チャージで6%のボーナスを追加するバーコードOPENCLAWを使用してください!


結論

主なポイントは単純です:CAPTCHAを解決することはワークフローの1つのステップにすぎません。実際のスクリーパーは、トークンを正しい方法で送信し、正しいリクエストの形を送信し、使用ケースに必要なフィールドを抽出する必要があります。

これはまた、これらのテンプレートが例として扱われるべきである理由です。別のサイトは、別のCAPTCHAタイプを使用し、トークンを別の場所に期待し、追加のcookiesやフィールドを必要とし、異なる応答の形を返し、異なる抽出または検証ロジックを必要とする可能性があります。

このテンプレートは次のためのスタートアップを提供します:

  • スクレイピングまたはデータ抽出
  • 製品モニタリング
  • 在庫チェック
  • 保護されたコンテンツの取得

これは次の広範なパターンを使用します:

トリガー -> CAPTCHAを解決 -> 保護されたリクエストを送信 -> 結果を抽出または検証 -> 出力

プレースホルダーを構成し、ワークフローをターゲットに一致させるまで非アクティブに保ち、使用ケースに合ったスケジュールまたはWebhookパスを有効にしてください。


よくある質問

自分のアカウントにログインするためにこれを使用できますか?

スクリーパーテンプレートは、認証トークンとともに資格情報をPOSTするHTTPリクエストノードを変更することで、ログインフローに適応できます。reCAPTCHA、Turnstileなどの専用のCAPTCHAタイプガイドを参照してください。準備済みのログインワークフローテンプレートが用意されています。

サイトが別のチャレンジタイプを使用している場合どうなりますか?

その場合、ワークフローを変更する必要があります。メインの例のreCAPTCHA設定とリクエストパターンは万能ではありません。CapSolverはCloudflare Turnstile、Cloudflare Challenge、GeeTest V3/V4、DataDome、AWS WAF、MTCaptchaなどに対応しています。CapSolverの解決ステップと保護されたリクエストを、ターゲットで使用されている実際のチャレンジタイプとトークン送信パターンに更新してください。

トークンをどこに送信すればよいですか?

ターゲットサイトが期待する場所に送信してください。これは次の可能性があります:

  • ヘッダー
  • フォームボディ
  • JSONペイロード
  • クエリパラメータ
  • クッキー
  • 隠しフィールド

価格モニターテンプレートはヘッダーを使用します。他のサイトは異なります。

各サイトごとにCapSolverの設定を変更する必要がありますか?

通常はい。同じCAPTCHAファミリーを使用するサイトでも、websiteURL、websiteKey、pageAction、非表示設定、またはその他のタスクオプションが異なる場合があります。

価格以外のものをスクレイピングできますか?

はい。選択肢や出力ロジックを交換して、在庫、タイトル、SKU、説明、保護されたコンテンツ、ログイン状態、サイトの健全性信号などが必要に応じて使用できます。

リクエストペイロードやセレクターが間違っているかどうかをどうやって確認できますか?

保護された応答をHTTPリクエストノードから確認することから始めます。

  • 応答が依然としてブロックされているか不完全な場合、リクエストの形がおそらく間違っています。
  • 応答が正しいが抽出に失敗した場合、セレクターまたはパースロジックがおそらく間違っています。

この順序でワークフローをデバッグしてください:解決 -> 送信 -> 応答を確認 -> 抽出。

もっと見る

n8nMar 09, 2026

CapSolver と n8n を使った reCAPTCHA v2/v3 の解決方法

CapSolverとn8nを使用してeCAPTCHA v2/v3ソルバーAPIを構築します。トークンの自動取得、ウェブサイトへの送信、保護されたデータの抽出をノーコードで自動化する方法を学びます。

Sora Fujimoto
Sora Fujimoto
Apr 22, 2026

画像パズルを解くための最高のAI:2026年のトップツールと戦略

画像パズルを解く最高のAIを発見してください。CapSolverのVision EngineとImageToText APIが、高い精度で複雑な視覚的課題を自動化する方法を学びましょう。

Sora Fujimoto
Sora Fujimoto

目次

web scrapingApr 22, 2026

Rust Web Scraping Architecture for Scalable Data Extraction

スケーラブルなRustウェブスクレイピングアーキテクチャを学びましょう。リクエスト、スクレイパー、非同期スクレイピング、ヘッドレスブラウザスクレイピング、プロキシローテーション、およびコンプライアンス対応のCAPTCHA処理で。

Sora Fujimoto
Sora Fujimoto
Apr 22, 2026

検索API対ナレッジサプライチェーン: AIデータインフラストラクチャガイド

検索APIツール、知識サプライチェーン、SERP APIワークフロー、およびAIデータパイプラインが、AI向けの現代のウェブデータインフラストラクチャを形成する方法を学びましょう。

Sora Fujimoto
Sora Fujimoto