AutomationFlowsWeb Scraping › Scrape Structured Google Search Results with Coreclaw and a Webhook

Scrape Structured Google Search Results with Coreclaw and a Webhook

Bycoreclaw @scraper on n8n.io

This workflow exposes a webhook that accepts a Google search query, runs the CoreClaw Google Search Scraper Worker via HTTP, and returns normalized organic results (title, URL, snippet, and position) as a structured JSON response. Receives a POST request on a webhook with a…

Webhook trigger★★★★☆ complexity9 nodesHTTP Request
Web Scraping Trigger: Webhook Nodes: 9 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #17926 — we link there as the canonical source.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "Google Search Scraper",
  "tags": [
    {
      "name": "scraping"
    },
    {
      "name": "seo"
    },
    {
      "name": "google-search"
    }
  ],
  "nodes": [
    {
      "id": "search-overview",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -400,
        80
      ],
      "parameters": {
        "width": 480,
        "height": 500,
        "content": "## Google Search Scraper\n\nRuns a Google search through the CoreClaw Google Search Scraper Worker and returns structured organic results for SEO, market research, monitoring, and AI-agent workflows.\n\n### Setup\n\nSet CORECLAW_API_KEY in n8n, activate the webhook, then send a query and optional locale settings.\n\n### Output\n\nReturns parsed search result data for downstream analysis or storage."
      },
      "typeVersion": 1
    },
    {
      "id": "search-step-1",
      "name": "Receive Query",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        140,
        100
      ],
      "parameters": {
        "color": 7,
        "width": 350,
        "height": 200,
        "content": "## Receive a search query\n\nProvide a query plus optional country and language settings."
      },
      "typeVersion": 1
    },
    {
      "id": "search-step-2",
      "name": "Run Search",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        550,
        100
      ],
      "parameters": {
        "color": 7,
        "width": 350,
        "height": 200,
        "content": "## Run Google search\n\nCoreClaw fetches current search results through its managed Worker API."
      },
      "typeVersion": 1
    },
    {
      "id": "search-step-3",
      "name": "Return Results",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        100
      ],
      "parameters": {
        "color": 7,
        "width": 350,
        "height": 200,
        "content": "## Return structured results\n\nNormalize search result records and return them in a webhook response."
      },
      "typeVersion": 1
    },
    {
      "id": "search-webhook",
      "name": "Receive Search Request",
      "type": "n8n-nodes-base.webhook",
      "position": [
        180,
        300
      ],
      "parameters": {
        "path": "google-search-scraper",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "search-format-query",
      "name": "Format Search Query",
      "type": "n8n-nodes-base.code",
      "position": [
        410,
        300
      ],
      "parameters": {
        "jsCode": "const body = $input.first().json.body || $input.first().json;\nconst query = body.query || body.q || body.keyword;\n\nif (!query) {\n  throw new Error('Send a query, for example: { \\\"query\\\": \\\"best CRM for small business\\\" }.');\n}\n\nreturn [{ json: {\n  query,\n  country: body.country || 'us',\n  language: body.language || 'en',\n  max_results: Number(body.max_results || 10),\n  timestamp: new Date().toISOString()\n} }];"
      },
      "typeVersion": 2
    },
    {
      "id": "search-run-worker",
      "name": "Run CoreClaw Search Scraper",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        670,
        300
      ],
      "parameters": {
        "url": "https://openapi.coreclaw.com/api/v2/workers/coreclaw~google-search-scraper/runs",
        "method": "POST",
        "options": {
          "timeout": 300000
        },
        "jsonBody": "={\n  \\\"input\\\": {\n    \\\"parameters\\\": {\n      \\\"custom\\\": {\n        \\\"query\\\": \\\"{{ $json.query }}\\\",\n        \\\"country\\\": \\\"{{ $json.country }}\\\",\n        \\\"language\\\": \\\"{{ $json.language }}\\\",\n        \\\"max_results\\\": {{ $json.max_results }}\n      }\n    }\n  },\n  \\\"is_async\\\": false\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer {{$env.CORECLAW_API_KEY}}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "search-parse-results",
      "name": "Normalize Search Results",
      "type": "n8n-nodes-base.code",
      "position": [
        920,
        300
      ],
      "parameters": {
        "jsCode": "const response = $input.first().json;\nif (response.code !== 0) {\n  return [{ json: { status: 'error', message: response.message || 'CoreClaw request failed' } }];\n}\n\nconst results = response.data?.list || response.data?.organic_results || [];\nreturn results.map((result, index) => ({\n  json: {\n    position: result.position || index + 1,\n    title: result.title || result.name || '',\n    url: result.url || result.link || '',\n    displayed_url: result.displayed_url || result.display_link || '',\n    snippet: result.snippet || result.description || ''\n  }\n}));"
      },
      "typeVersion": 2
    },
    {
      "id": "search-respond",
      "name": "Return Search Results",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        1180,
        300
      ],
      "parameters": {
        "options": {
          "responseCode": 200
        },
        "respondWith": "json",
        "responseBody": "={\n  \\\"status\\\": \\\"success\\\",\n  \\\"query\\\": \\\"{{ $('Format Search Query').first().json.query }}\\\",\n  \\\"country\\\": \\\"{{ $('Format Search Query').first().json.country }}\\\",\n  \\\"result_count\\\": {{ $('Normalize Search Results').all().length }},\n  \\\"results\\\": {{ JSON.stringify($('Normalize Search Results').all().map(item => item.json)) }}\n}"
      },
      "typeVersion": 1.1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Format Search Query": {
      "main": [
        [
          {
            "node": "Run CoreClaw Search Scraper",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Receive Search Request": {
      "main": [
        [
          {
            "node": "Format Search Query",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Search Results": {
      "main": [
        [
          {
            "node": "Return Search Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run CoreClaw Search Scraper": {
      "main": [
        [
          {
            "node": "Normalize Search Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow exposes a webhook that accepts a Google search query, runs the CoreClaw Google Search Scraper Worker via HTTP, and returns normalized organic results (title, URL, snippet, and position) as a structured JSON response. Receives a POST request on a webhook with a…

Source: https://n8n.io/workflows/17926/ — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Web Scraping

This workflow enables the submission of business-critical URLs via the Google Indexing API and IndexNow.

HTTP Request, XML
Web Scraping

Never miss important website updates again! This workflow automatically tracks changes on dynamic websites (think React apps, JavaScript-heavy sites) and sends you instant email notifications when som

HTTP Request, Google Sheets, Gmail
Web Scraping

This template implements a recursive web crawler inside n8n. Starting from a given URL, it crawls linked pages up to a maximum depth (default: 3), extracts text and links, and returns the collected co

HTTP Request
Web Scraping

Crawl Space & Foundation Repair Intake AI - Vapi MVP (Client Template). Uses httpRequest, googleSheets. Webhook trigger; 14 nodes.

HTTP Request, Google Sheets
Web Scraping

JD Scraper. Uses httpRequest. Webhook trigger; 8 nodes.

HTTP Request