# Google Search Scraper | Organic, Ads & People Also Ask (`genial_candlestand/google-search-results-scraper`) Actor

Get Google search results as flat rows: organic rank, title, real URL, domain and snippet, plus text ads with advertiser, People also ask questions and related searches. Many keywords per run, any country, language, city and time range, ads included in the page price, no login.

- **URL**: https://apify.com/genial_candlestand/google-search-results-scraper.md
- **Developed by:** [Flowo](https://apify.com/genial_candlestand) (community)
- **Categories:** SEO tools, Developer tools, AI
- **Features:** Limited permissions
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.62 / 1,000 search results pages

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Search Scraper | Organic, Ads & People Also Ask

![Google Search Scraper | Organic, Ads & People Also Ask](https://api.apify.com/v2/key-value-stores/Ll7RrWtDkZYOrBvfE/records/google-search-search-engine-results-banner-6037f2a9.png)

Get Google search results for any keyword and country as flat rows: the rank, title, real target URL, domain, site name and snippet of each organic result, plus text ads with advertiser and landing page, People also ask questions and related searches. Every row says its query, country, location and page, so you can sort and filter it in a spreadsheet straight away. One price per results page with ads, People also ask and related searches included.

### What does Google Search Scraper do?

You give it a list of keywords, a country and optionally a language, a city and a time filter. It searches Google for each keyword, reads one or more results pages and saves every result on the page as one row with a `type`: `organic`, `ad`, `peopleAlsoAsk` or `relatedSearch`. It is built for SEO rank tracking, PPC competitor research, content ideas and developers or AI agents that need a simple Google search API.

### How to scrape Google search results

![Google Search Scraper output example: Query, Page, Type, Position, Title](https://api.apify.com/v2/key-value-stores/Ll7RrWtDkZYOrBvfE/records/google-search-search-engine-results-output-85f0709d.png)

![How Google Search Scraper works: Searches google.com for each query in your country, language and city; Reads up to 20 results pages per query, following Google's next page; Retries a blocked page wit](https://api.apify.com/v2/key-value-stores/Ll7RrWtDkZYOrBvfE/records/google-search-search-engine-results-how-9b8b8a5e.png)

1. Open the actor in Apify Console.
2. Enter your keywords in **Search queries**, one per line. Google operators like `site:`, `intitle:`, `"exact phrase"` and `-word` work.
3. Set **Country** (two-letter code, default `US`). Optionally set **Language**, **City or region**, **Time range** and **Pages per query**.
4. Click **Start** and wait for the run to finish.
5. Open the **Organic results** or **Overview** view of the dataset, or export it as JSON, CSV or Excel.

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

Price per event by Apify plan:

| Event | Free | Bronze | Silver | Gold and above |
|---|---|---|---|---|
| Search results page | $6.60 per 1,000 | $5.94 per 1,000 | $5.28 per 1,000 | $4.62 per 1,000 |
| Actor start | $0.00005 | $0.00005 | $0.00005 | $0.00005 |

A test run with the API example input below returned 28 rows in 11 s.

You pay for **one event per Google results page** for one query (`search-page`). All rows of that page are included: about 10 organic results, any text ads, People also ask questions and related searches. In test runs a page gave about 14–18 rows. There is no add-on for ads.

Not charged:

- pages with no organic results and no ads (for example with a narrow time range or past the last page);
- pages that failed after retries;
- resolving Google redirect links to the real URL.

A small start fee of $0.00005 is charged once per run.

| Scenario | Events | Cost on the Free plan |
|---|---|---|
| 3 keywords × 1 page (the prefilled input) | 3 pages | about $0.02 |
| 100 keywords × 1 page (rank check of the top 10) | 100 pages | about $0.66 |
| 100 keywords × 3 pages (top 30 positions) | 300 pages | about $1.98 |
| 1,000 keywords × 1 page | 1,000 pages | about $6.60 |

### Input

![Google Search Scraper input example: Search queries, Country, Pages per query, Time range, Resolve real organic URLs](https://api.apify.com/v2/key-value-stores/Ll7RrWtDkZYOrBvfE/records/google-search-search-engine-results-input-cbae35fa.png)

| Field | What it does |
|---|---|
| `queries` (required) | Keywords, one per line. Operators and any script work. Empty lines and duplicates are skipped. |
| `country` | Two-letter ISO country code, default `US` (`UK` is accepted as `GB`). Sets Google's country, the proxy exit country and pins the search location. |
| `language` | Google interface language, e.g. `en`, `de`, `pt-BR`. Empty = the main language of the country. |
| `location` | A city or region inside the country, as `City,Region,Country`, e.g. `Austin,Texas,United States`. |
| `maxPagesPerQuery` | Results pages per query, 1–20, default 1. Stops earlier when Google has no next page. |
| `timeRange` | `any`, `hour`, `day`, `week`, `month` or `year`, default `any`. |
| `resolveUrls` | Resolve Google's `google.com/goto?url=…` organic links to the real target URL, default `true`. |

Example input:

```json
{
  "queries": ["pizza delivery"],
  "country": "US",
  "location": "Austin,Texas,United States",
  "maxPagesPerQuery": 2,
  "timeRange": "any",
  "resolveUrls": true
}
```

### What data can you extract from Google search results?

| Field | Description |
|---|---|
| `query`, `country`, `language`, `location`, `page` | What was searched, where and on which results page |
| `type` | `organic`, `ad`, `peopleAlsoAsk` or `relatedSearch` |
| `position` | Rank. Organic ranks continue across pages (page 2 continues after the last organic result of page 1); other types are numbered within the page |
| `title` | Result title, ad headline, question or related search text |
| `url` | Organic: the target page; ad: the landing page; questions and related searches: a Google search link |
| `urlResolved` | Organic only: `true` when `url` is the real target, `false` when it is still Google's redirect link |
| `domain` | Host of the target or landing page without `www.` |
| `displayedUrl` | Breadcrumb shown under the title |
| `siteName` | Site name of an organic result or the advertiser of an ad |
| `description` | Snippet of an organic result or the ad text |
| `publishedText` | Date shown in the snippet, as Google shows it in the search language |
| `adPlacement` | Ads only: `top` or `bottom` of the page |
| `scrapedAt` | When the row was extracted |

Example rows from a real run (query "car insurance", US):

```json
[
  {
    "query": "car insurance", "country": "US", "language": "en", "location": "United States",
    "page": 1, "type": "organic", "position": 1,
    "title": "Car Insurance | Get An Auto Insurance Quote",
    "url": "https://www.allstate.com/auto-insurance", "urlResolved": true,
    "domain": "allstate.com", "displayedUrl": "https://www.allstate.com › auto-insurance",
    "siteName": "Allstate",
    "description": "We offer a range of flexible auto coverage, including liability, collision and comprehensive. Get a quote in minutes. …",
    "publishedText": null, "scrapedAt": "2026-11-05T15:38:37.532Z"
  },
  {
    "query": "car insurance", "country": "US", "language": "en", "location": "United States",
    "page": 1, "type": "peopleAlsoAsk", "position": 1,
    "title": "Who currently has the cheapest car insurance?",
    "url": "https://www.google.com/search?q=Who%20currently%20has%20the%20cheapest%20car%20insurance%3F",
    "urlResolved": null, "domain": null, "displayedUrl": null, "siteName": null,
    "description": null, "publishedText": null, "scrapedAt": "2026-11-05T15:38:37.532Z"
  },
  {
    "query": "car insurance", "country": "US", "language": "en", "location": "United States",
    "page": 1, "type": "relatedSearch", "position": 1,
    "title": "Car insurance quotes",
    "url": "https://www.google.com/search?q=Car%20insurance%20quotes",
    "urlResolved": null, "domain": null, "displayedUrl": null, "siteName": null,
    "description": null, "publishedText": null, "scrapedAt": "2026-11-05T15:38:37.532Z"
  }
]
```

### Use cases

- **Rank tracking for SEO:** run your keyword list for a country, filter the `organic` rows by your `domain` and read your `position` next to your competitors'.
- **Competitor ads monitoring for PPC:** see who advertises on a keyword, with which headline, text and landing page, and whether the ad is at the top or bottom.
- **Local search:** set a city such as `Austin,Texas,United States` to see the results a searcher there gets.
- **Content ideas in other markets:** search `kaffee` in `DE` and collect People also ask questions and related searches in German.
- **Fresh results and research for AI:** combine `site:` and other operators with a time range such as `month`, and fetch several pages per query.

### Limitations

- People also ask rows contain the **question only**, not the answer. AI Overviews, sitelinks, the total result count and other SERP widgets are not returned.
- Google shows text ads on only some commercial searches (in tests about 1 in 5 commercial pages), so many pages have no `ad` rows.
- `publishedText` is filled only when Google shows a date in the snippet, and is kept as shown ("Jun 29, 2026", "vor 3 Stunden"), not converted to a date.
- Some organic rows (e.g. videos) have no snippet, so `description` can be empty.
- If a Google redirect link cannot be resolved, the row keeps the Google link with `urlResolved: false`.
- Up to 20 pages per query. Google may have fewer pages; the actor then stops early.
- Speed: with link resolution about 10 pages per minute, without it about 25 pages per minute.

### Tips and troubleshooting

- **More positions:** raise **Pages per query**; each page adds about 10 organic results and is one event.
- **Faster runs:** turn off **Resolve real organic URLs** if Google's redirect links are fine for you. Then some organic `url` values are `google.com/goto?url=…` links with `urlResolved: false`, and `domain` comes from the displayed URL.
- **City searches:** write the location as `City,Region,Country` in English, and it must be in the selected country. A city in another country fails the run before any search; an unknown or non-canonical name (like `Austin, TX`) is sent with a warning, and Google may ignore it.
- **Few or no rows with a time range:** narrow ranges such as `hour` or `day` can return pages without organic results. Those pages are not saved and not charged; the log names the query and page.
- **Multilingual countries:** set **Language** yourself (e.g. `fr` for Switzerland), because an empty language uses the country's main one.
- **Run failed at once:** check the log for an input error: an unknown country or language code, an empty query list, or a location outside the country.

### API, MCP and integrations

Run the actor from your code with the same JSON input as in Console. Your API token is in [Console → Settings → API & Integrations](https://console.apify.com/settings/integrations).

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("genial_candlestand/google-search-results-scraper").call(run_input={"queries": ["coffee", "car insurance"], "country": "US"})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

**Node.js** (`npm install apify-client`):

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('genial_candlestand/google-search-results-scraper').call({"queries": ["coffee", "car insurance"], "country": "US"});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**HTTP** — one request runs the actor and returns the results (runs up to 5 minutes; longer ones: [run asynchronously](https://docs.apify.com/api/v2/act-runs-post)):

```bash
curl -X POST "https://api.apify.com/v2/acts/genial_candlestand~google-search-results-scraper/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"queries":["coffee","car insurance"],"country":"US"}'
```

**AI agents (MCP).** Add the actor as a tool of the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp). Claude Code:

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=genial_candlestand/google-search-results-scraper"
```

Claude Desktop, Cursor or VS Code: `{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=genial_candlestand/google-search-results-scraper"}}}`. Then ask, for example:

- "Find the Google rank of nike.com for best running shoes and trail running shoes in the US"
- "Who advertises on Google for car insurance in the UK? List headlines and landing pages"
- "Get People also ask questions and related searches for kaffee on Google Germany"

**Integrations.** Run it on a schedule with [Apify Schedules](https://docs.apify.com/platform/schedules) and send the results to Google Sheets, Slack, Zapier, Make, n8n or your webhook — see [Apify integrations](https://docs.apify.com/platform/integrations).

### FAQ

**Is it legal to scrape Google search results?**<br>
The actor collects only what Google shows publicly on its results pages, with no login. You are responsible for how you use the data and for following the laws and terms that apply to you.

**Do I need a Google account, API key or my own proxy?**<br>
No. The actor uses Apify's Google SERP proxy in the country you choose. There is no proxy setting to configure.

**Are ads charged extra?**<br>
No. Text ads, People also ask questions and related searches are part of the page price, and a page without ads costs the same as one with ads.

**Why is a page not charged?**<br>
A page with no organic results and no ads, or a page that failed after retries, is not saved and not charged. The log says which query and page.

**How is it different from other Google search scrapers?**<br>
Each result is a flat row with a `type`, instead of one item per page with nested arrays. Ads, People also ask and related searches are included in one page price, and Google's redirect links are resolved to real URLs. Other actors offer more SERP widgets, such as AI Overviews and People also ask answers, which this actor does not return.

### Also useful

- [Google Trends Scraper](https://apify.com/genial_candlestand/google-trends-scraper) — check search interest over time, by region and related queries for the keywords you rank for
- [Google Ads Transparency Scraper](https://apify.com/genial_candlestand/google-ads-transparency-scraper) — see all ads an advertiser you found in the results runs on Google
- [Google News Scraper](https://apify.com/genial_candlestand/google-news-articles-search-scraper) — get news articles for the same keywords with source and publish time
- [Google Trends Trending Now Scraper](https://apify.com/genial_candlestand/google-trending-now-scraper) — find what people search for right now in a country to pick new keywords

# Actor input Schema

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

Keywords to search on Google, one per line. Operators work (site:, intitle:, "exact phrase", -word) in any language. Each query gives its organic results, ads, People also ask questions and related searches as rows. Empty lines and duplicates are skipped.

## `country` (type: `string`):

Two-letter country code of the Google results, e.g. US, DE, JP, BR, GB (UK also works). Sets Google's country and the proxy country. An unknown code stops the run before any search.

## `language` (type: `string`):

Google interface language, e.g. en, de, ja, pt-BR. Leave empty to use the main language of the country (US→en, DE→de, JP→ja). Set it yourself for multilingual countries.

## `location` (type: `string`):

Get results as seen in one city or region of the selected country. Write it as City,Region,Country in English, e.g. Austin,Texas,United States or Munich,Bavaria,Germany. Empty = the whole country.

## `maxPagesPerQuery` (type: `integer`):

Google results pages per query, 1–20 (about 10 organic results each). Stops earlier when Google has no next page. Each page is one charged event.

## `timeRange` (type: `string`):

Only results from this period, like Google's Tools → Any time filter. Narrow ranges can return few or no results; empty pages are free.

## `resolveUrls` (type: `boolean`):

Turn Google's redirect links (google.com/goto?url=…) into the real target URL, free, about 1.5 s per link. Turn off for faster runs; unresolved rows keep the Google link with urlResolved false.

## Actor input object example

```json
{
  "queries": [
    "coffee",
    "best running shoes",
    "car insurance"
  ],
  "country": "US",
  "maxPagesPerQuery": 1,
  "timeRange": "any",
  "resolveUrls": true
}
```

# Actor output Schema

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

Dataset with one row per result (filter by the type field)

## `overview` (type: `string`):

The main columns of every row

# 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": [
        "coffee",
        "best running shoes",
        "car insurance"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("genial_candlestand/google-search-results-scraper").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": [
        "coffee",
        "best running shoes",
        "car insurance",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("genial_candlestand/google-search-results-scraper").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": [
    "coffee",
    "best running shoes",
    "car insurance"
  ]
}' |
apify call genial_candlestand/google-search-results-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,genial_candlestand/google-search-results-scraper"
        }
    }
}
```

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/XGwJMoxid4g9el8Nc/builds/q3YlqGDmavtJAJb1C/openapi.json
