# Google SERP Scraper

> Scrape Google organic results: title, URL (exact page or site homepage, flagged by urlType), breadcrumb and snippet. Build the query from market, industry and location. Pay per result.

Actor id `quaking_pail/google-serp-scraper`. Index of all Epsimo actors: https://epsimo.org/llms.txt

## What it does

### Google SERP Scraper

Google SERP Scraper extracts organic Google Search results and converts them into structured, keyword-rich rows for lead generation, market research, SEO monitoring and prospect discovery. It builds queries from market/industry terms, location and exact-phrase targets, fetches Google result pages over plain HTTP via a Google-focused proxy (no headless browser), parses and returns each result’s title, destination address (either the exact result page or the site’s homepage when the page link is obfuscated), the breadcrumb/visible path, the snippet text, tracked/emphasized keywords found in title/snippet, and a marker indicating link precision; it deduplicates results across pages, applies site/path filters, and reports the split between exact-page links and site-origin rows for downstream processing.

### Use cases

- Build lists of agencies, consultancies or businesses in a specific city or niche for sales outreach.  
- Find marketing agencies, shops or local service providers by query and location.  
- Collect company websites to feed contact-enrichment or contact-finding workflows.  
- Track which domains appear for target keywords for SEO monitoring.  
- Research competitors and client landscapes for agencies and freelancers.  
- Provide structured organic search results to developers and AI agents for automated analysis.

## Use cases and Limits

From the actor README on the Apify Store.

### Use cases for Google search results data

- Find marketing agencies, consultancies or shops in a given city.
- Collect company websites to pass to a contact finder.
- Track which domains appear for your target keywords.

### How much will it cost to scrape Google search results?

You **pay per result, with no subscription** and no rental. One result is one organic search result saved to the dataset. Failed pages, retries and empty runs never create result charges. A small standard Actor start event applies to every run. See the **Pricing** tab for current prices, including discounts on higher Apify plans.

Set a **maximum cost per run** and the Actor stops at that limit and keeps the results already saved. If the limit is too low for even one result, the run fails without charging any result.

### Tips for scraping Google

- Results come from Google in English for the US; put the city in **Location** to narrow them.
- Lower **Maximum Results** for quick checks, and raise it when you want more exact links: later pages often carry more plaintext links than page 1.
- Make the query specific. Narrow queries return more company websites and fewer directory pages.
- If a run fails with "No search results were scraped", Google blocked the requests or the query has no organic results. Keep the proxy on the default `GOOGLE_SERP` group and run it again.

### FAQ, disclaimers and support

#### Is it legal to scrape Google search results?

Our Actors are ethical and do not extract any private user data. Google SERP Scraper only reads what Google shows in public search results: titles, links, breadcrumbs and snippets. A snippet can contain whatever the page shows publicly, such as a business email address or phone number. We therefore believe that our Actors, when used for ethical purposes by Apify users, are safe. However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

#### Why did my run fail with no results?

The Actor fails a run that saves nothing, so you can tell a blocked or empty search from a successful one, and no result is charged. Check the log for `429` or CAPTCHA messages and make sure the proxy is the default `GOOGLE_SERP` group.

#### Why do some results only contain the homepage?

Google encrypts the link behind many results. The Actor cannot decode it, so it saves the site's homepage from the breadcrumb and marks the row `urlType: "origin"`. Rows with `urlType: "exact"` hold the result page itself. See [Exact links and site origins](https://apify.com/quaking_pail/google-serp-scraper#exact-links-and-site-origins).

#### Why is displayedUrl not a plain domain?

`displayedUrl` is the breadcrumb Google shows under the title, such as `www.sortlist.com › Marketing › Marketing Automation`. Use `url` when you need a clean address.

#### How do I report a problem?

Open an issue in the **Issues** tab with the run ID. If the Actor saved you time, a rating on the **Reviews** tab helps other users find it.

## Input

| Name | Type | Required | Default | Allowed values / range | Description |
|---|---|---|---|---|---|
| `search_query_base` | string | yes | - | - | The base query for the search, representing the market or type of company to target. Example: marketing agency. |
| `domain` | string | no | `""` | - | The specific domain or industry to add to the search query, for example AI or e-commerce. Leave blank to leave it out of the query. |
| `location` | string | no | `""` | - | The location to add to the search query, for example a city or country. Leave blank to search without a location. |
| `info_to_retrieve` | string | no | `""` | - | An exact phrase Google must match, such as email or website. It is added to the query in quotes. Leave blank to leave it out of the query. |
| `max_results` | integer | no | `100` | min 1; max 300 | The maximum number of search results to save. Google shows about 10 results per page, and the scraper reads at most 30 pages. |
| `proxyConfiguration` | object | no | `{"useApifyProxy": true, "apifyProxyGroups": ["GOOGLE_SERP"]}` | - | Proxy used to load Google. GOOGLE_SERP is the recommended group: it is built for Google result pages and billed per request. Other groups may be rate-limited by Google with HTTP 429. |

## Example input

Built from the input schema prefill/default values (the actor publishes no example input).

```json
{
  "search_query_base": "marketing agency",
  "domain": "IA",
  "location": "Paris",
  "info_to_retrieve": "email, website",
  "max_results": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "GOOGLE_SERP"
    ]
  }
}
```

## Output

| Field | Type | Description |
|---|---|---|
| `title` | string or null | Title of the search result as shown on Google |
| `url` | string or null | Real target URL of the result. Google /url and /goto wrappers are removed. When Google encrypts the link, this is the site origin (homepage); see urlType. |
| `displayedUrl` | string or null | Breadcrumb Google shows under the title (site and path), or the hostname of the URL when Google shows none |
| `description` | string or null | Snippet text Google shows under the result |
| `emphasizedKeywords` | array or null | Tracked keywords (agence, marketing) found in the title or snippet |
| `type` | string or null | Result type. Always organic. |
| `urlType` | string or null | exact: url is the deep link Google returned. origin: Google encrypted the link, so url is the site's homepage taken from the breadcrumb. |

Dataset views: `overview` (Overview).

## Example output item

Built from the `example` values of the dataset schema.

```json
{
  "title": "Example Marketing Agency | Paris",
  "url": "https://www.example.com/agency",
  "displayedUrl": "www.example.com › agency",
  "description": "Example agency offering digital marketing services in Paris.",
  "emphasizedKeywords": [
    "marketing"
  ],
  "type": "organic",
  "urlType": "exact"
}
```

## Pricing

Pay per event, in effect since 2026-10-16 (as of 2026-10-18). Each event below is charged.

| Event | Title | Description | Price USD (FREE tier) |
|---|---|---|---|
| `apify-actor-start` | Actor Start (once per run) | Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). | $0.00005 |
| `apify-default-dataset-item` | Search result (primary) | One organic Google search result saved to the default dataset. Failed searches are never charged. | $0.0011 |

Plan-tier prices for `apify-default-dataset-item`: FREE $0.0011, BRONZE $0.001, SILVER $0.0009, GOLD $0.0008, PLATINUM $0.0008, DIAMOND $0.0008.

Prices are in USD at the Apify FREE plan tier; tiered events can cost less on paid Apify plans (plan-tier prices above). The [Apify Store page](https://apify.com/quaking_pail/google-serp-scraper) is authoritative: read the current price there instead of hardcoding these values.

## How to run

Run the actor and get its dataset items in one HTTP call (needs an Apify API token in `$APIFY_TOKEN`, sent in the `Authorization` header as Apify recommends ([Apify API authentication](https://docs.apify.com/api/v2))):

```bash
curl -X POST "https://api.apify.com/v2/acts/quaking_pail~google-serp-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "search_query_base": "marketing agency",
  "domain": "IA",
  "location": "Paris",
  "info_to_retrieve": "email, website",
  "max_results": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "GOOGLE_SERP"
    ]
  }
}'
```

Apify also accepts `?token=$APIFY_TOKEN` in the URL, but avoid it: URLs end up in logs and shell history.

If the run takes longer than 300 seconds, this endpoint returns HTTP 408 (Request Timeout). For longer runs start the actor with the asynchronous [Run Actor endpoint](https://docs.apify.com/api/v2/act-runs-post) and read the dataset when the run finishes. The `maxTotalChargeUsd` query parameter caps the total cost of a run ([run-sync-get-dataset-items reference](https://docs.apify.com/api/v2/act-run-sync-get-dataset-items-post)).

## Apify MCP

Apify hosts an MCP server at https://mcp.apify.com. The actor id is `quaking_pail/google-serp-scraper`; the `tools` query parameter loads only that actor as a tool ([Apify MCP server](https://docs.apify.com/platform/integrations/mcp)).

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=quaking_pail/google-serp-scraper",
      "headers": {
        "Authorization": "Bearer $APIFY_TOKEN"
      }
    }
  }
}
```

Replace `$APIFY_TOKEN` with your Apify API token. Without the `headers` entry the client signs in to Apify with OAuth in the browser instead.

## Links

- Apify Store: [quaking_pail/google-serp-scraper](https://apify.com/quaking_pail/google-serp-scraper)
- Sources: [actor API](https://api.apify.com/v2/acts/quaking_pail~google-serp-scraper), [build API](https://api.apify.com/v2/acts/quaking_pail~google-serp-scraper/builds/default)
- Data fetched from the Apify API on 2026-10-18
- Build: 0.8.2

## Do not

- Do not hardcode prices: read them on the Apify Store page before a large run.
- Do not put the Apify token in shared URLs, prompts or logs; prefer the `Authorization` header.
- Do not treat the output as verified: it is scraped from public pages and can be incomplete, outdated or wrong.
