# Google SERP Scraper: Organic Results, PAA & Related (`physealabs/google-serp-extractor`) Actor

Turn search queries into clean rows: rank, title, URL, domain and snippet, plus People also ask and related searches. Built by Physea Labs (Liminal). Launch Sale: 90% OFF for the first week. From $0.0015 per results page.

- **URL**: https://apify.com/physealabs/google-serp-extractor.md
- **Developed by:** [jay casey](https://apify.com/physealabs) (community)
- **Categories:** SEO tools, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$1.50 / 1,000 results page scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Google SERP Scraper: Organic Results, PAA & Related

Type search queries and get the results page as clean rows: rank, title, URL, domain and snippet for every organic result, plus the People also ask questions and related searches Google shows.

🚀 **Launch Sale: 90% OFF for the first week!** Prices below are the regular rates; launch-week runs are billed at a tenth of them.

### What can it do?

| What you get | Features |
|---|---|
| 🔎 Organic results with rank, title, URL, domain, snippet | ⚡ Plain HTTP, no browser: a 2-query run finishes in seconds |
| ❓ People also ask and related searches as their own rows | 🛡️ Apify Google SERP proxy on the platform, Bing / DuckDuckGo fallback if Google blocks |
| 🏷️ `source_engine` on every row so you know where it came from | 📤 JSON, CSV, Excel, API, Zapier, Make, n8n |

### Who this is for

- SEO teams tracking who ranks for their keywords
- Content teams mining People also ask questions for briefs
- Lead generation: find the companies ranking for a niche query
- LLM agents that need fresh search results as structured rows

### What you get back

| Field | Type | What you get | Example |
|---|---|---|---|
| `recordType` | `string` | `organic`, `people_also_ask`, `related_search` or `status` | `organic` |
| `query` | `string` | The query you typed | `web scraping api` |
| `position` | `integer` | Rank within its record type | `1` |
| `title` | `string` | Result title, question or related search | `ScrapingBee - The Best Web Scraping API` |
| `url` | `string` | Result URL (organic rows) | `https://www.scrapingbee.com/` |
| `domain` | `string` | Host without www | `scrapingbee.com` |
| `snippet` | `string` | Description under the result | `ScrapingBee is the best web scraping API...` |
| `source_engine` | `string` | `google`, `bing` or `duckduckgo` | `google` |
| `status` | `string` | `ok` or `error` | `ok` |

Every run also writes `RUN_SUMMARY.json` to the key-value store (counts, spend-limit flag, pricing).

### What you need to provide

| Field | Type | What it does | Example |
|---|---|---|---|
| `queries` | `array` | One search per line, typed exactly as you would in Google. | `["web scraping api", "best python http client"]` |
| `maxResultsPerQuery` | `integer` | Organic results to keep per query. Each 10 results is one results page. | `10` |
| `countryCode` | `string` | Two-letter country code for localized results (us, gb, de, in...). | `"us"` |
| `languageCode` | `string` | Interface language code (en, de, fr...). | `"en"` |
| `includeSerpFeatures` | `boolean` | Add one row per People also ask question and related search found on the first page. | `true` |
| `fallbackToDuckDuckGo` | `boolean` | If Google answers with a captcha or JavaScript wall, fetch the same query from Bing (then DuckDuckGo) so the run still returns organic rows. Each row's source_engine says which engine it came from. Turn off for Google-only data. | `true` |

#### Quick start

1. Click **Try for free**.
2. Press **Start**: the sample input finishes in under a minute with no API keys or setup.
3. Replace the sample with your own values and run again.
4. Open the dataset, or export it as JSON, CSV or Excel.

### Pricing

🚀 **Launch Sale: 90% OFF for the first week!**

- `serp-page-scraped`: **$0.0015** per results page (up to 10 organic results + SERP features), so 1,000 results cost $0.15.
- Blocked or empty pages are not charged.
- Set a max cost per run in the run options and the run stops cleanly when it hits it.
- Normal Apify platform usage applies.

### Limits and honest notes

- Google blocks most datacenter IPs. On Apify each page goes through the Google SERP proxy; when Google still challenges a request and the fallback is on, the query is answered from Bing (then DuckDuckGo) and `source_engine` says so. Turn the fallback off if you need Google-only data.
- Ads, shopping, maps and AI Overview boxes are not extracted. For AI Overview citations use our *Google Brand Mention & Citation Tracker*.
- Up to 100 results per query (10 pages).
- No other Apify actor is called: everything is collected in-house over plain HTTP.

### Run it from code

Same input as the Console sample:

```json
{
  "queries": [
    "web scraping api",
    "best python http client"
  ],
  "maxResultsPerQuery": 10
}
```

```sh
curl -X POST "https://api.apify.com/v2/acts/physealabs~google-serp-extractor/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" -d @input.json
```

```python
from apify_client import ApifyClient
items = ApifyClient("YOUR_APIFY_TOKEN").actor("physealabs/google-serp-extractor").call(run_input={"queries": ["web scraping api", "best python http client"], "maxResultsPerQuery": 10})
```

It also works from Zapier, Make, n8n and Apify schedules.

### About Physea Labs · Liminal

Built and maintained by **Physea Labs**: the same extraction layer that feeds [Liminal](https://physea.ai), our grounded research and decision engine. If it is good enough to feed Liminal's citations, it is good enough for your pipeline.

# Actor input Schema

## `queries` (type: `array`):

One search per line, typed exactly as you would in Google.

## `maxResultsPerQuery` (type: `integer`):

Organic results to keep per query. Each 10 results is one results page.

## `countryCode` (type: `string`):

Two-letter country code for localized results (us, gb, de, in...).

## `languageCode` (type: `string`):

Interface language code (en, de, fr...).

## `includeSerpFeatures` (type: `boolean`):

Add one row per People also ask question and related search found on the first page.

## `fallbackToDuckDuckGo` (type: `boolean`):

If Google answers with a captcha or JavaScript wall, fetch the same query from Bing (then DuckDuckGo) so the run still returns organic rows. Each row's source_engine says which engine it came from. Turn off for Google-only data.

## Actor input object example

```json
{
  "queries": [
    "web scraping api",
    "best python http client"
  ],
  "maxResultsPerQuery": 10,
  "countryCode": "us",
  "languageCode": "en",
  "includeSerpFeatures": true,
  "fallbackToDuckDuckGo": true
}
```

# Actor output Schema

## `results` (type: `string`):

One row per item; error rows explain anything that was skipped and are never charged.

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "web scraping api",
        "best python http client"
    ],
    "maxResultsPerQuery": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("physealabs/google-serp-extractor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": [
        "web scraping api",
        "best python http client",
    ],
    "maxResultsPerQuery": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("physealabs/google-serp-extractor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "web scraping api",
    "best python http client"
  ],
  "maxResultsPerQuery": 10
}' |
apify call physealabs/google-serp-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,physealabs/google-serp-extractor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/BoV7GGlx8X4W4vcxJ/builds/EJ1aKTAsy9s1Uum6X/openapi.json
