# Google Search Results Scraper - SERP, Organic & PAA (`zaver.api/google-search-scraper`) Actor

Scrape Google search results for any keyword - organic rankings with position, title, link and snippet, plus People Also Ask questions. Country, language and date-range filters, deep pagination, and billing per row delivered. No proxies, no API key, no login.

- **URL**: https://apify.com/zaver.api/google-search-scraper.md
- **Developed by:** [Zaver](https://apify.com/zaver.api) (community)
- **Categories:** SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.29 / 1,000 search results

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 Search Results Scraper - SERP, Organic Results & PAA

**Scrape Google search results at scale - no proxies, no CAPTCHAs, no browser to babysit.** Give it a list of keywords and get back one clean row per result: organic listings and People Also Ask, each tagged with the query and page it came from.

> ⭐ bulk keyword lists · country + language + date filters · deep pagination · pay per row delivered · CSV/JSON/Excel · API, MCP & schedules

### What data does it extract?

One row per result, with the `query`, `page` and `type` it came from so multi-query exports stay
separable. Fields Google does not return for an item are simply absent, and any new field Google
adds is passed through automatically.

| Field | Description |
|---|---|
| `title` | Result headline |
| `link` | Destination URL |
| `snippet` | Description text Google shows |
| `position` | Rank within the page |
| `date` | Publication date, where Google shows one |
| `sitelinks` | Sub-links under the result |
| `question` | The question text, on People Also Ask rows |
| `type` | `organic` or `people_also_ask` |
| `query` | The keyword this row came from |
| `page` | Which SERP page it came from |

#### Example output

```json
{
  "query": "coffee shops new york",
  "page": 1,
  "type": "organic",
  "title": "Best Specialty Coffees in New York — Drips Of God",
  "link": "https://www.dripsofgod.com/new-york",
  "snippet": "La Cabra (East Village) · Devoción (Williamsburg, Flatiron, Downtown Brooklyn) · Café Leon Dore (Nolita) · Café Integ...",
  "position": 1
}
```

### How to use it

1. Paste your queries into **`queries`** - one per line.
2. Set the options you need from the table below.
3. Run it, then download the dataset as **CSV, Excel, JSON, JSONL or XML** - or read it straight from
   the Apify API.

#### Input example

```json
{
  "queries": [
    "best crm software",
    "coffee shops new york"
  ],
  "gl": "us",
  "hl": "en",
  "dateRange": "qdr:w",
  "maxPages": 3
}
```

| Option | Type | Description |
|---|---|---|
| `queries` | array | **Required.** Keywords, one per line. |
| `gl` | string | Country code - `us`, `in`, `gb`, `de`... |
| `hl` | string | Language code - `en`, `hi`, `es`... |
| `dateRange` | string | `qdr:h`, `qdr:d`, `qdr:w`, `qdr:m`, `qdr:y` - past hour to past year. |
| `maxPages` | integer | Pages per keyword, default 1. Each page is one request. |

### Pricing

| Event | Price |
|---|---|
| `serp-result` | **$0.29 per 1,000 results** ($0.00029 per result) |

1,000 results → **$0.29** · 10,000 → **$2.90** · 100,000 → **$29.00**

You are billed per row delivered, as it is delivered. Queries that fail or return nothing cost you
nothing, and an interrupted run only ever bills the rows already in your dataset.

### Use cases

#### Track keyword rankings by country and language

Run the same keyword set on a schedule with `gl` and `hl` set to each market you sell in, then diff the `position` column between runs to see what moved.

#### Monitor which competitors rank for your keywords

Export the top pages for your category every morning and watch which domains enter or leave the first two pages.

#### Mine People Also Ask for content and FAQ ideas

PAA rows arrive as question/answer pairs - a ready-made brief of what searchers actually ask about a topic.

#### Monitor new pages ranking for your brand

Set `dateRange` to `qdr:d` or `qdr:h` and each run returns only pages Google started ranking in that window - a cheap mention-monitoring feed.

#### Build URL and snippet datasets for research or RAG pipelines

One row per result with clean links and snippets feeds straight into an embedding or summarisation step.

### Good to know

- Google returns roughly 10 organic results per page; use `maxPages` for depth.
- Rows are organic results plus People Also Ask; Google's news and top-story blocks are not part of this endpoint's response.
- `dateRange` applies to search results and changes what Google returns.
- Rows carry `query`, `page` and `type` so multi-keyword exports stay separable.

### Frequently asked questions

#### Do I need proxies, an API key or a Google account?

No. Requests run through hosted Google search infrastructure on our side - there is nothing to configure and no key to supply.

#### How many results can I get per keyword?

Google serves about 10 organic results per page, plus People Also Ask rows on the first page. Depth comes from `maxPages` (up to 100), and each page is one request. Asking for a bigger page size does not return more than Google shows.

#### How do I get results as a user in another country sees them?

Set `gl` to the country and `hl` to the language, for example `gl: de` with `hl: de`. Rankings genuinely differ per market, so this matters for rank tracking.

#### Can I limit results to recent pages only?

Yes. `dateRange` accepts `qdr:h` (past hour), `qdr:d`, `qdr:w`, `qdr:m` and `qdr:y`.

#### How do I export Google rankings to CSV or Excel?

Every run writes to a dataset you can download as CSV, Excel, JSON, JSONL or XML, or pull through the Apify API.

#### Can I schedule daily rank tracking?

Yes - use Apify schedules, or trigger runs from the API, MCP server, Make, Zapier or n8n.

#### What am I charged for if a keyword returns nothing?

Nothing. Billing is per row delivered, so empty or failed queries cost you nothing.

### Related Google scrapers

- [Google Images Scraper](https://apify.com/zaver.api/google-images-scraper) - image URLs, sizes and source pages
- [Google Videos Scraper](https://apify.com/zaver.api/google-videos-scraper) - video results across YouTube, TikTok and the web
- [Google Places Scraper](https://apify.com/zaver.api/google-places-scraper) - local business results with phone and website
- [Google Maps Scraper](https://apify.com/zaver.api/google-maps-scraper) - map places with GPS, hours and Place ID
- [Google Patents Scraper](https://apify.com/zaver.api/google-patents-scraper) - patents with inventors, assignees and dates
- [Google Shopping Scraper](https://apify.com/zaver.api/google-shopping-scraper) - products with prices, sellers and ratings

***

*Not affiliated with or endorsed by Google. Returns publicly available search results.*

# Actor input Schema

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

Search queries, one per line.

## `gl` (type: `string`):

Two-letter country code for localised results, e.g. <code>us</code>, <code>in</code>, <code>th</code>, <code>gb</code>. Leave empty for default.

## `hl` (type: `string`):

Interface language code, e.g. <code>en</code>, <code>hi</code>, <code>th</code>. Leave empty for default.

## `dateRange` (type: `string`):

Restrict results to a recent period.

## `maxPages` (type: `integer`):

How many result pages to fetch per query. You are billed only per row delivered.

## Actor input object example

```json
{
  "queries": [
    "apple inc"
  ],
  "gl": "",
  "hl": "",
  "dateRange": "",
  "maxPages": 1
}
```

# Actor output Schema

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

One dataset item per result.

## `resultsCsv` (type: `string`):

CSV download.

## `runSummary` (type: `string`):

Counts for the run.

# 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": [
        "apple inc"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("zaver.api/google-search-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": ["apple inc"] }

# Run the Actor and wait for it to finish
run = client.actor("zaver.api/google-search-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": [
    "apple inc"
  ]
}' |
apify call zaver.api/google-search-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,zaver.api/google-search-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/VPd6JtmMue460YGQQ/builds/3r36QfVH4Vrc5mq7s/openapi.json
