# Google Trends Scraper (`meticulous_ground/google-trends-scraper`) Actor

Google Trends API and pytrends alternative: interest over time, by region, related queries/topics, and trending now as flat rows. Up to 5 keywords, any country. Pay only for delivered rows - no start fees, failed keywords never charged. Automatic session rotation for reliability.

- **URL**: https://apify.com/meticulous\_ground/google-trends-scraper.md
- **Developed by:** [Aaron S](https://apify.com/meticulous_ground) (community)
- **Categories:** SEO tools, News, Developer tools
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 data row delivereds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Google Trends Scraper

Pull Google Trends data (interest over time, interest by region, related queries, trending now) as flat, ready-to-use rows, with automatic session rotation and no charge for keywords that fail.

### Try it

Paste this into the input editor and hit Run:

```json
{
  "mode": "interest_over_time",
  "keywords": ["bitcoin", "ethereum"],
  "geo": "GB",
  "timeRange": "today 12-m",
  "resolution": "COUNTRY",
  "maxItems": 1000
}
```

#### Input fields

| Field | Type | Values | Notes |
|---|---|---|---|
| `mode` | string | `interest_over_time` | `interest_by_region` | `related` | `trending_now` | Which Trends report to pull |
| `keywords` | array | up to 5 terms | Leave empty only for `trending_now` |
| `geo` | string | ISO code, e.g. `GB`, `US`, `GB-SCT` | Empty means worldwide |
| `timeRange` | string | e.g. `today 12-m`, `now 7-d` | Google Trends time-range syntax |
| `resolution` | string | `COUNTRY` | `REGION` | `CITY` | Only used by `interest_by_region` |
| `maxItems` | integer | e.g. `1000` | Caps rows delivered before the run stops |
| `proxyGroups` | array | e.g. `["RESIDENTIAL"]` | Apify proxy groups; RESIDENTIAL (default) recommended - Google blocks most datacenter IPs |

### Output

Every mode returns flat rows, one per data point. No nested objects to unpack. Each row carries `keyword`, `geo`, `timeRange`, `mode`, and `fetchedAt`, plus fields specific to the mode below.

#### `interest_over_time`

```json
{
  "keyword": "bitcoin",
  "geo": "GB",
  "timeRange": "today 12-m",
  "mode": "interest_over_time",
  "fetchedAt": "2026-07-19T12:00:00.000Z",
  "date": "Jan 1, 2025",
  "time": "1704067200",
  "value": 42
}
```

#### `interest_by_region`

```json
{
  "keyword": "bitcoin",
  "geo": "GB",
  "timeRange": "today 12-m",
  "mode": "interest_by_region",
  "fetchedAt": "2026-07-19T12:00:00.000Z",
  "location": "Scotland",
  "geoCode": "GB-SCT",
  "value": 88
}
```

#### `related`

```json
{
  "keyword": "bitcoin",
  "geo": "GB",
  "timeRange": "today 12-m",
  "mode": "related",
  "fetchedAt": "2026-07-19T12:00:00.000Z",
  "query": "bitcoin etf",
  "value": 250,
  "formattedValue": "Breakout",
  "rankingType": "rising"
}
```

`rankingType` is `top` or `rising`, matching the two lists Google Trends returns per keyword.

#### `trending_now`

```json
{
  "keyword": "",
  "geo": "GB",
  "timeRange": "",
  "mode": "trending_now",
  "fetchedAt": "2026-07-19T12:00:00.000Z",
  "title": "Scotland match",
  "traffic": "50K+",
  "pubDate": "Tue, 25 Aug 2026 15:00:00 -0700"
}
```

Keywords that fail after retries are logged to a separate `errors` dataset (`keyword`, `mode`, `reason`, `fetchedAt`) instead of leaving a silent gap in your results.

### Coming from pytrends?

The [pytrends](https://github.com/GeneralMills/pytrends) library is archived (last commit August 2024, 150+ open issues) - Google's endpoint changes, cookie requirements, and 429 blocks are what killed it, and they're exactly what this actor handles for you: session-scoped cookies, residential proxy rotation, and retries with identity rotation on every 429.

| pytrends call | This actor |
|---|---|
| `interest_over_time()` | `"mode": "interest_over_time"` |
| `interest_by_region()` | `"mode": "interest_by_region"` (+ `resolution`) |
| `related_queries()` / `related_topics()` | `"mode": "related"` (both, tagged by `source`) |
| `trending_searches()` | `"mode": "trending_now"` |
| `kw_list=[...]` | `"keywords": [...]` (up to 5) |
| `geo='GB'`, `timeframe='today 12-m'` | `"geo": "GB"`, `"timeRange": "today 12-m"` (same syntax) |

### How this compares

|  | This actor | Typical Trends actors on the Store |
|---|---|---|
| Charge on failed keywords | Never - only delivered rows are billed | Often bills per run regardless of failed items |
| Actor start | Free - no per-run fee | Some popular Trends actors charge $0.02 per run before any data lands |
| Output shape | Flat rows, one per data point | Frequently nested per-keyword JSON you have to unpack |
| Reliability approach | Automatic session rotation (Crawlee session pool) and bounded retries with backoff | Not usually documented in the listing |

We don't have 30 days of canary data yet, so we're not publishing a success-rate number - just the mechanics above, which you can verify in the run log.

### Pricing

Pay-per-event, priced on delivered rows. The free tier is $0.002 per row, tiering down as your volume grows. Starting a run costs nothing - you're billed only once rows land in your dataset. If a keyword fails after retries, it goes to the `errors` dataset instead, and you pay nothing for it.

### Using the API

#### Apify API (HTTP)

```bash
curl "https://api.apify.com/v2/acts/meticulous_ground~google-trends-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "interest_over_time",
    "keywords": ["bitcoin"],
    "geo": "GB",
    "timeRange": "today 12-m"
  }'
```

#### JavaScript (apify-client)

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });

const run = await client.actor('meticulous_ground/google-trends-scraper').call({
  mode: 'interest_over_time',
  keywords: ['bitcoin'],
  geo: 'GB',
  timeRange: 'today 12-m',
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### Python (apify-client)

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run = client.actor("meticulous_ground/google-trends-scraper").call(run_input={
    "mode": "interest_over_time",
    "keywords": ["bitcoin"],
    "geo": "GB",
    "timeRange": "today 12-m",
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

Swap `mode`/`keywords`/`geo`/`timeRange` for any of the four modes above.

# Actor input Schema

## `mode` (type: `string`):

Which Google Trends report to scrape.

## `keywords` (type: `array`):

Up to 5 terms. Leave empty only for Trending now.

## `geo` (type: `string`):

ISO country/region code, e.g. GB, US, GB-SCT. Empty = worldwide.

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

Google Trends time range expression, e.g. 'today 12-m', 'now 7-d'.

## `resolution` (type: `string`):

Geographic granularity for interest\_by\_region results.

## `maxItems` (type: `integer`):

Maximum number of result rows to deliver before stopping.

## `proxyGroups` (type: `array`):

Apify proxy groups to route requests through. RESIDENTIAL is recommended - Google Trends blocks most datacenter IPs. Empty = automatic datacenter proxies.

## Actor input object example

```json
{
  "mode": "interest_over_time",
  "keywords": [
    "bitcoin"
  ],
  "geo": "GB",
  "timeRange": "today 12-m",
  "resolution": "COUNTRY",
  "maxItems": 1000,
  "proxyGroups": [
    "RESIDENTIAL"
  ]
}
```

# Actor output Schema

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

No description

## `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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("meticulous_ground/google-trends-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("meticulous_ground/google-trends-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 '{}' |
apify call meticulous_ground/google-trends-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,meticulous_ground/google-trends-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/Q25ka1BLM538PikkY/builds/ItsyKpRg9y8hEDQPn/openapi.json
