# Google Trends Data Scraper — SEO Keyword Research Tool (`afanasenko/google-trends-scraper`) Actor

Get Google Trends interest over time and by region, related queries, rising searches and related topics. Compare 2–5 keywords and export complete reports to JSON, CSV or Excel.

- **URL**: https://apify.com/afanasenko/google-trends-scraper.md
- **Developed by:** [Andrey Afanasenko](https://apify.com/afanasenko) (community)
- **Categories:** SEO tools, Developer tools, Automation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $120.00 / 1,000 trend reports

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 Trends Data Scraper — SEO Keyword Research Tool

[![Apify Actor](https://apify.com/actor-badge?actor=afanasenko/google-trends-scraper)](https://apify.com/afanasenko/google-trends-scraper)

> **Find seasonal demand, compare keywords, and discover related searches with Google Trends data.**
> Get interest over time and by region for SEO research, content planning, and market analysis.

> **🆓 Free to start:** Get one complete keyword report or a comparison of 2–5 keywords per run.
> FREE accounts include up to three checks per month. Completed reports use your Apify credits at the FREE rate.

### 🎯 What it does

Choose a country, language, period, and search type, then pick how you want to study your keywords.

| Mode | Input | What it returns |
|---|---|---|
| **Full Keyword Reports** (`full`) | Up to 20 phrases in `keywords` | One independent report per phrase: timeline, regions, related queries, and related topics. |
| **Compare Keywords** (`compare`) | 2–5 phrases in `compareKeywords` | One comparison report with a shared timeline scale and regional comparisons. |

**You get** one dataset row per completed report, ready to export as JSON, CSV, or Excel.
**The scores show relative interest**, not monthly search counts. Use comparison mode to compare phrases on one scale.

> ⚠️ **Pick your mode first.** Fill the keyword list for that mode. Both mode sections stay visible.
> Example: selecting `full` but filling only `compareKeywords` leaves the full list empty and starts the `running shoes` demo.

### 📦 Output sample

**What's in a row:**

- **Your request** — `reportId`, `mode`, `keywords`, `country`, `language`, `timeRange`, and `searchType`.
- **Interest** — `interestOverTime` and `interestByRegion`, with values in the order of the report's keywords.
- **Related searches** — `relatedQueries` and `relatedTopics`, each with top and rising lists in full reports.
- **Coverage and checks** — `status`, `sectionStatuses`, `normalization`, `collectedAt`, and a Google Trends `checkUrl`.

A real full report from October 7, 2026. Lists below show selected entries; exports contain every returned entry.

```json
{
  "reportId": "aKFIa9eAkiLGmaS3S_1",
  "mode": "full",
  "keywords": ["running shoes"],
  "country": "US",
  "language": "en",
  "timeRange": "past_12_months",
  "searchType": "web",
  "status": "ok",
  "checkUrl": "https://trends.google.com/trends/explore?hl=en&geo=US&date=today%2012-m&q=running%20shoes",
  "collectedAt": "2026-10-07T14:43:16.946Z",
  "interestOverTime": [{"dateFrom":"2025-10-05","dateTo":"2025-10-11","timestamp":1759622400,"missingData":false,"values":[16]}],
  "interestByRegion": [{"geoId":"US-WY","geoName":"Wyoming","maxValueIndex":0,"values":[100]}],
  "relatedQueries": {"top":[{"query":"men's running shoes","value":100}],"rising":[{"query":"brooks adrenaline gts 25","value":7650}]},
  "relatedTopics": {"top":[{"topicId":"/m/06rrc","topicTitle":"Shoes","topicType":"Shoe","value":100}],"rising":[{"topicId":"/m/04kfh24","topicTitle":"Fasciitis","topicType":"Inflammation","value":450}]},
  "sectionStatuses": {"interestOverTime":"ok","interestByRegion":"ok","relatedQueries":"ok","relatedTopics":"ok"},
  "normalization": {"time":"report_peak_100","regions":"report_region_peak_100","keywords":["running shoes"],
    "note": "Relative Google Trends indices, not search counts. Comparison keywords share a time scale. Region and time scales are distinct. Independent full reports cannot be compared as one scale."
  }
}
```

Zero stays `0`; missing values stay `null`. Optional details absent from the source stay absent.
Labels such as `Breakout` are preserved. Comparisons return `null` for related queries and topics, with `not_available` section statuses.

**Views** — four ways to inspect the same report rows in **Storage → Dataset**:

| View | What each row is | Best for |
|---|---|---|
| **Trend reports** (default) | One report, showing keywords, settings, status, collection time, and the verification link. | Reviewing completed reports. |
| **Interest over time** | The same rows, trimmed to keywords, timeline, normalization, and section statuses. | Seasonal demand and comparison charts. |
| **Regional interest** | The same rows, trimmed to keywords, regions, normalization, and section statuses. | Geographic research. |
| **Related queries and topics** | The same rows, trimmed to keywords, related lists, and section statuses. | Content ideas and keyword discovery. |

Views keep the lists inside each report. They do not create a separate row for each date, region, or query.
The full dataset schema is included in the [Apify build definition](https://api.apify.com/v2/acts/afanasenko~google-trends-scraper/builds/default), under `actorDefinition.storages.dataset`.

### ⚡ Quick start

1. **Pick your mode first** in **Operation mode**. Both keyword sections stay visible; fill only the matching list.
2. For your first full report, enter `running shoes` in **Mode 1: Full Keyword Reports**.
3. Keep the default market and settings, click **Start**, then open **Storage → Dataset**.

The equivalent JSON input is:

```json
{"mode":"full","keywords":["running shoes"]}
```

This requests one complete report and fits the FREE allowance when a monthly check remains.
Country defaults to the United States, language to English, period to 12 months, and search type to Google Search.

**Clicking Start with an empty form runs a demo.** Full mode uses `running shoes`; comparison mode uses `tea` and `coffee`.
Each demo produces one report and uses the normal report charge and monthly allowance. Examples are placeholders, not prefilled keywords.

### 🧭 When to use it

- **SEO research** — check whether interest in a topic is growing before building a page around it.
- **Content calendars** — find recurring peaks and publish before the next seasonal increase.
- **Product planning** — compare product phrases within the same country and period.
- **Local marketing** — see where relative interest is strongest before choosing target regions.
- **YouTube research** — use the YouTube search type to compare interest in video topics.

Start with one market and one period. Change one setting at a time when exploring differences.
For comparisons across several keywords, keep them together in one comparison report.

### 🛠 Input

**Operation mode** appears first, above the sections. The form then groups keyword lists and shared settings:

| Section | Purpose |
|---|---|
| **🎯 Mode 1: Full Keyword Reports** | Enter independent keywords for full reports. |
| **🎯 Mode 2: Compare Keywords** | Enter the keywords you want to compare together. |
| **🌍 Market** | Choose the country and language. |
| **📊 Report settings** | Choose the time range and search type. |

- **`mode`** — set this first: `full` or `compare`. Fill only its keyword section; both sections remain visible.
- **`keywords`** — full mode only; up to 20 distinct phrases, one per line.
- **`compareKeywords`** — comparison mode only; 2–5 distinct phrases, one per line.
- **`country`** — select a supported country code; default `US`.
- **`language`** — select a supported language code; default `en`.
- **`timeRange`** — choose one of the eight periods below; default `past_12_months`.
- **`searchType`** — `web`, `news`, `youtube`, `images`, or `shopping`; default `web`.

| Time-range value | Period |
|---|---|
| `past_hour` | Past hour |
| `past_4_hours` | Past four hours |
| `past_day` | Past day |
| `past_7_days` | Past seven days |
| `past_30_days` | Past 30 days |
| `past_90_days` | Past 90 days |
| `past_12_months` | Past 12 months |
| `past_5_years` | Past five years |

Use phrases of 2–100 characters. Duplicate phrases and comma-separated lists inside a single entry are rejected before collection.
For older API integrations, comparison mode also accepts `keywords` when `compareKeywords` is absent.

### 💰 How much will scraping Google Trends cost?

Billing uses Apify's **Pay Per Event** model with one primary event: **Trend report** (`REPORT`).
There is no starting fee. One completed full report or one completed comparison counts as one event.

| Apify plan | Price per Trend report |
|---|---:|
| FREE | $0.180 |
| BRONZE | $0.150 |
| SILVER | $0.135 |
| GOLD / PLATINUM / DIAMOND | $0.120 |

**Pricing math:**

| Request | Plan | Report charge |
|---|---|---:|
| One full keyword report | FREE | $0.180 |
| One comparison of five keywords | BRONZE | $0.150 |
| Ten independent full reports | BRONZE | $1.500 |
| Twenty independent full reports | GOLD | $2.400 |

A completed check with `no_data` is billed: the requested search was checked successfully.
Errors, incomplete reports, and locked rows are not billed as Trend reports.

Set **Maximum cost per run** in Apify's run options to control spending. It is not an actor input field.
Before collecting another report, the actor checks whether the remaining budget can cover its report charge.

### 🆓 Free vs paid plan

| Feature | FREE plan | Paid plan |
|---|---|---|
| Full reports per run | One keyword | Up to 20 keywords |
| Comparison per report | 2–5 keywords | 2–5 keywords |
| Related queries and topics | Included in the full report | Included in every full report |
| Monthly allowance | Up to three checks per user | No FREE monthly cap |
| Report content | Complete report | Complete report |
| Recovery of an interrupted run | Supported | Supported |

On FREE, extra independent keywords appear as **locked rows** without further collection or report charges.
Monthly limits are tracked centrally. Deleting a run's storage does not replenish the allowance.

If the monthly allowance is exhausted, collection does not start. Temporary allowance-service outages also stop collection.
Both cases show an explanation and create no report charges.

Upgrade to process multiple independent keywords in one run and continue beyond the FREE monthly allowance.
The FREE rate uses Apify credits; the allowance does not waive report charges.

### 🧪 Recipes

Copy these inputs into the JSON editor, then adjust the keywords and market.

**Find seasonality for several product phrases**

```json
{
  "mode": "full", "keywords": ["running shoes", "trail running shoes", "walking shoes"]
}
```

Each phrase gets a full report and its own scale. FREE returns the first report and locks the remaining two.

**Compare demand on a shared scale**

```json
{
  "mode": "compare", "compareKeywords": ["tea", "coffee", "matcha"]
}
```

All three phrases share one comparison report and one report charge. Related lists are unavailable in comparison mode.

**Research a Spanish YouTube topic**

```json
{
  "mode": "full", "keywords": ["zapatillas de correr"],
  "country": "ES", "language": "es",
  "timeRange": "past_90_days", "searchType": "youtube"
}
```

This checks interest in YouTube searches for Spain over the past 90 days.

### 🔁 Resume / checkpoint

To recover an interrupted run, use **Resurrect** on that same run in Apify Console.
A saved, already-paid report can be delivered without collecting or charging for it again.

When a collection or payment outcome is uncertain, the actor stops instead of automatically repeating it.
Check the run message before trying again. Starting a new run requests fresh reports and can create new charges.

### 📡 Live status & storage records

Open **Storage → Key-value store → `status.html`** to follow progress and see the final next step.
The run also saves these records:

| Storage key | Type | What it holds |
|---|---|---|
| `status.html` | HTML | Progress, delivered reports, budget information, and the run's message. |
| `RUN_SUMMARY` | JSON | Report counts, billing status, timing, settings, and the stop reason. |
| `USER_MESSAGE` | JSON | A plain-language result message and suggested next step. |
| `FREE_LIMITS_APPLIED` | JSON | FREE restrictions applied during the run, when applicable. |
| `SKIPPED_ITEMS` | JSON | Keywords skipped because of limits or errors, when present. |
| `REPORT_STATE` | Encrypted JSON | The recovery journal; an internal record, not an output export. |

Use dataset rows for your analysis. Use `RUN_SUMMARY` and `USER_MESSAGE` to monitor runs from your own workflow.
If billing confirmation is pending, the status records show it as pending rather than as a zero charge.

### 🤖 Programmatic / API use

**REST API:** start a comparison using your Apify token.

```bash
curl -X POST \
  'https://api.apify.com/v2/acts/afanasenko~google-trends-scraper/runs' \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"mode":"compare","compareKeywords":["tea","coffee"],"country":"US","language":"en"}'
```

Wait for the run to finish, then read its `defaultDatasetId` through the [Apify API](https://docs.apify.com/api/v2).
Schedules and integrations can send completed results into your regular reporting workflow.

**MCP and AI agents:** connect a compatible client to the [Apify MCP server](https://docs.apify.com/integrations/mcp).
An authorized agent can inspect the actor's inputs, run it, and read the results.
For example: *“Compare tea and coffee in the United States over the past 12 months.”*

### 💡 Tips & Best Practices

#### Getting maximum results

- Start with full mode to discover related queries and topics around one seed phrase.
- Move your shortlisted phrases into comparison mode to assess them together.
- Keep country, period, and search type consistent when reviewing a group of keywords.

#### Cost optimization

- Compare 2–5 phrases together when you need relative demand: the group counts as one report.
- Check your keywords before starting. A completed `no_data` check still uses a report charge.
- Set Maximum cost per run before starting a batch, and reuse downloaded results for repeated analysis.

#### Performance

- Keep full-report batches within 20 phrases. Larger lists are rejected before collection starts.
- Use comparison mode when a single shared report answers your question.
- Recover an interrupted run with Resurrect before starting a replacement run.

#### Data quality

- Open `checkUrl` to spot-check a report in Google Trends with the same settings.
- Read `sectionStatuses` before using a list; unavailable sections are not zero interest.
- Keep `0`, `null`, and `Breakout` distinct. Do not convert missing values into measured zeros.

### ❓ FAQ

**How do I find seasonal keywords for SEO?** Run a full report over 12 months and inspect recurring peaks. Use related queries to expand your research.

**Is there a free way to try this Google Trends scraper?** FREE accounts can check one full report or one comparison per run, up to three times per month, using Apify credits.

**Can I use the official Google Trends API instead?** Google offers a [Trends API alpha with limited access](https://developers.google.com/search/apis/trends). This actor provides reports through Apify.

**What alternatives should I use for keyword research?** Use Google Trends for manual exploration. Use a search-volume tool when you need monthly counts rather than relative interest.

**Can I compare results from separate full reports?** Their peaks are normalized independently. Use comparison mode for a shared time scale; regional and time scales also differ.

**Does a score of 100 mean 100 searches?** No. It is a relative index. Scores do not give absolute search counts or prove that one market has more searches.

**Why are some values null or some sections unavailable?** The source did not supply those values. Comparison mode omits related lists; absent optional fields remain absent instead of becoming zero.

**Why was a no-data report charged?** The check completed successfully but found no usable trend data. Errors, incomplete reports, and FREE locked rows do not trigger REPORT.

**Why did I get a demo instead of my keywords?** The selected mode's list was empty. Both sections remain visible; fill `keywords` for full or `compareKeywords` for comparison.

**Does an empty-input demo use my monthly allowance?** Yes. It is one normal report, announced as a demo. The full sample is running shoes; the comparison sample is tea and coffee.

**What happens if collection or payment confirmation fails?** Check `USER_MESSAGE` and `RUN_SUMMARY`. Confirmed zero-cost failures may be retried; unknown outcomes are held to avoid duplicate purchases or charges.

**How fast is a report?** Run time varies with the query and service availability. Open the live status page to follow progress.

### 🔗 Other related actors (same author)

| Your goal | Actor | Why choose it |
|---|---|---|
| Seasonality, relative demand, and keyword comparisons | **This Google Trends Scraper** | Timelines, regions, and related searches. |
| Monthly search volumes and advertising metrics | [Keyword Search Volume](https://apify.com/afanasenko/keyword-search-volume) | Search volume and keyword metrics rather than trend indices. |
| Links pointing to a website | [Backlink Scraper](https://apify.com/afanasenko/backlink-scraper) | Backlink research alongside keyword planning. |

### 🛟 Support & feedback

Open an [issue in Apify Console](https://console.apify.com/actors/zyw0irn52b9UmsgFa/issues) with the run ID and your expected result.
Include the selected mode and settings so the result can be reproduced. Keep access tokens out of your message.

If the actor helps your research, a [Store review](https://apify.com/afanasenko/google-trends-scraper) helps other users choose it.

### ⚖️ Is it legal to scrape Google Trends?

[Google Trends data](https://developers.google.com/search/docs/monitor-debug/trends-start) describes aggregate search interest. This actor does not collect individual search histories or private accounts.
Use the data in accordance with [Google's terms](https://policies.google.com/terms) and the rules that apply to your use case.

# Changelog

This Actor's version history is a separate document: https://apify.com/afanasenko/google-trends-scraper/changelog.md

# Actor input Schema

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

Choose the mode first. Mode 1 collects an independent full report for each keyword. Mode 2 compares 2–5 keywords in one report.

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

Mode 1 only. Enter up to 20 distinct keyword phrases, one per line.

## `compareKeywords` (type: `array`):

Mode 2 only. Enter 2–5 distinct keyword phrases, one per line. Related queries and topics are available in Mode 1.

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

Country for Google Trends interest. Default: United States.

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

Language for Google Trends results and related terms. Default: English.

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

Period to collect. Default: past 12 months.

## `searchType` (type: `string`):

Google service to explore. Default: Google Search.

## Actor input object example

```json
{
  "mode": "full",
  "keywords": [],
  "country": "US",
  "language": "en",
  "timeRange": "past_12_months",
  "searchType": "web"
}
```

# Actor output Schema

## `reports` (type: `string`):

No description

## `liveStatus` (type: `string`):

No description

## `userMessage` (type: `string`):

No description

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

No description

## `freeLimitsApplied` (type: `string`):

No description

## `skippedItems` (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("afanasenko/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("afanasenko/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 afanasenko/google-trends-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,afanasenko/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/zyw0irn52b9UmsgFa/builds/3wrvWVI4r5kda1hwd/openapi.json
