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

Extract Google Trends data: interest over time, interest by region, related queries, and Trending Now searches with news articles, plus category and location lists.

- **URL**: https://apify.com/crawlstone/google-trends-scraper.md
- **Developed by:** [Crawl Stone](https://apify.com/crawlstone) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 1,000 explore results

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 Scraper

We built Google Trends Scraper to give you Google Trends data as clean, structured results: compare search interest over time and by region, find related searches, and collect what is trending right now, without copying charts by hand.

Instead of managing browsers, cookies, or proxies yourself, choose a mode, enter your search terms, and get one ready-to-use row per result.

> **Unofficial Actor:** This is an independent tool and is not affiliated with, authorized, or endorsed by Google.

***

### What you can do with this Actor

#### 1. Explore search interest (`explore`)

Get the same three result types you see on the Google Trends **Explore** page, for one search or a batch of up to 100:

- **Interest over time:** a timeline of search interest from 0 to 100 for each term.
- **Interest by region:** how interest is spread across countries, subregions, metros, or cities.
- **Related queries:** the top and rising searches related to each term.

Each line in **Search queries** is one Google Trends comparison. Put up to 5 terms on one line, separated by commas, to compare them on one scale, just like adding terms on the website. Add more lines to run a batch of independent searches in one run.

You can narrow every search by location, time range (every website preset or your own dates), category, and search type (web, image, news, YouTube, or Google Shopping). Turn off result types you don't need to pay less.

#### 2. Collect Trending Now searches (`trendingNow`)

Get the searches trending in a country over the past 4 hours, 24 hours, 48 hours, or 7 days, in Google's order. Each trend includes its search volume, increase, start and end time, categories, related searches, and up to 30 news articles.

#### 3. Look up categories and locations (`exploreCategories` and `exploreGeos`)

Get the complete lists of Google Trends categories and locations. Use them to find the category ID or location code for your Explore and Trending Now runs. These modes need no other input.

***

### Quick Start

1. Click **Try for free** on the Actor page.
2. Leave **Mode** on **Explore search interest**. The input is prefilled with a comparison of `bitcoin` and `ethereum` in the United States.
3. Click **Start**.
4. Open the **Dataset** tab when the run finishes.

For your first run, you can use the prefilled input:

```json
{
  "mode": "explore",
  "geo": "US",
  "searchQueries": ["bitcoin, ethereum"]
}
```

This returns one interest-over-time row and one interest-by-region row for the comparison, plus one related-queries row for each term: four rows in total.

***

### Input Guide

Only the fields used by your selected mode are read; the others are ignored. The Actor checks your input before it starts. If something is invalid, the run fails right away with a message explaining what to fix, and you are not charged.

#### Location (`geo`)

**Location** is used by both `explore` and `trendingNow` and defaults to `US`. Enter a Google Trends location code:

- A country, such as `US`, `GB`, or `ID`.
- A subregion, such as `US-CA`.
- A metro area, such as `US-CA-807`.
- `WW` for worldwide. Worldwide is available in `explore` only, because Google Trends has no worldwide Trending Now list.

Run **List Explore locations** (`exploreGeos`) to see every supported code. Each row's `code` can be used directly as **Location**.

#### Explore inputs

| Input | What it does |
| --- | --- |
| `searchQueries` | 1–100 lines. Each line is one comparison of 1–5 comma-separated terms. |
| `timeRange` | `now 1-H`, `now 4-H`, `now 1-d`, `now 7-d`, `today 1-m`, `today 3-m`, `today 12-m` (default), `today 5-y`, `all` (2004 to present), or `custom`. |
| `customTimeRange` | Required when `timeRange` is `custom`: a start and end date as `YYYY-MM-DD YYYY-MM-DD`. |
| `category` | A Google Trends category ID. `0` (default) means all categories. Run **List Explore categories** to see every ID. |
| `property` | The Google search the interest comes from: `""` web search (default), `images`, `news`, `youtube`, or `froogle` (Google Shopping). |
| `includeInterestOverTime`, `includeInterestByRegion`, `includeRelatedQueries` | Turn each result type on or off. All are on by default; keep at least one on. |
| `regionResolution` | The level used for interest by region: `""` Google's default, `COUNTRY`, `REGION` (subregion), `DMA` (metro), or `CITY`. |

Location, time range, category, and search type apply to every line in the run. To compare searches with different settings, use separate runs.

This example compares three terms in the United States over a custom date range and returns only interest over time and related queries:

```json
{
  "mode": "explore",
  "geo": "US",
  "searchQueries": ["chatgpt, gemini, claude"],
  "timeRange": "custom",
  "customTimeRange": "2025-01-01 2025-06-30",
  "includeInterestByRegion": false
}
```

This example runs a batch of three separate searches worldwide over the past 5 years:

```json
{
  "mode": "explore",
  "geo": "WW",
  "searchQueries": ["running shoes", "hiking boots", "yoga mat"],
  "timeRange": "today 5-y"
}
```

#### Trending Now inputs

| Input | What it does |
| --- | --- |
| `geo` | The country to list trends for. `WW` is not supported. |
| `hours` | `4`, `24` (default), `48`, or `168` (7 days). |
| `maxArticlesPerTrend` | News articles to return for each trend, `0`–`30`. Defaults to `3`. When `hours` is `168`, at most `3` is allowed. |

```json
{
  "mode": "trendingNow",
  "geo": "GB",
  "hours": "24",
  "maxArticlesPerTrend": 5
}
```

#### Category and location lists

```json
{
  "mode": "exploreCategories"
}
```

Use `"mode": "exploreGeos"` for the location list.

***

### Data Structure & Examples

Every row has a `type` field that tells you what it contains: `interestOverTime`, `interestByRegion`, `relatedQueries`, `trend`, `category`, `geo`, or `error`. The **Dataset** tab has a view for each mode, and the Explore views are split by result type. Every view also shows the `type` and `message` columns, so you can spot error rows.

Explore rows always include the settings they were made with (`terms`, `geo`, `timeRange`, `category`, `property`) and `resolvedTime`, the actual date range Google used. Each row therefore stands on its own, even in a large batch.

Results keep Google's order and are not deduplicated. Explore rows follow the order of your input lines. Times are in UTC, and labels such as `formattedTime` are in English.

JSON exports keep the nested structure shown below. Tabular exports such as CSV or Excel flatten or serialize nested fields.

#### Interest over time (`interestOverTime`)

*This is an abridged preview, not a complete Dataset row.*

```json
{
  "type": "interestOverTime",
  "terms": ["bitcoin", "ethereum"],
  "geo": "US",
  "timeRange": "today 3-m",
  "resolvedTime": "2026-07-14 2026-10-14",
  "timeline": [
    {
      "timestamp": "2026-07-14T00:00:00Z",
      "formattedTime": "Jul 14, 2026",
      "values": [66, 11],
      "formattedValues": ["66", "11"],
      "hasData": [true, true],
      "partial": false
    }
  ],
  "averages": [53, 8]
}
```

- `values` holds one number per term, in the order of `terms`.
- `partial` is `true` for the latest point when Google's data for that period is still incomplete.
- `averages` is filled only for comparisons of two or more terms.

#### Interest by region (`interestByRegion`)

*This is an abridged preview, not a complete Dataset row.*

```json
{
  "type": "interestByRegion",
  "terms": ["bitcoin"],
  "geo": "US",
  "resolution": "REGION",
  "regions": [
    {
      "geoName": "Kansas",
      "geoCode": "US-KS",
      "values": [100],
      "formattedValues": ["100"],
      "hasData": [true],
      "maxValueIndex": 0
    }
  ]
}
```

- `resolution` is the level Google used.
- Country, subregion, and metro regions have a `geoCode`. City regions have `coordinates` (`lat`, `lng`) instead.

#### Related queries (`relatedQueries`)

There is one row for each term, so a comparison of three terms returns three related-queries rows.

*This is an abridged preview, not a complete Dataset row.*

```json
{
  "type": "relatedQueries",
  "terms": ["bitcoin"],
  "term": "bitcoin",
  "top": [
    {
      "query": "bitcoin price",
      "value": 100,
      "formattedValue": "100",
      "exploreUrl": "https://trends.google.com/trends/explore?q=bitcoin+price&date=today+3-m&geo=US"
    }
  ],
  "rising": [
    {
      "query": "british man recovers lost bitcoin",
      "value": 12250,
      "formattedValue": "Breakout",
      "exploreUrl": "https://trends.google.com/trends/explore?q=british+man+recovers+lost+bitcoin&date=today+3-m&geo=US"
    }
  ]
}
```

- `top` values are relative interest from 0 to 100.
- `rising` values show the increase. Google shows them as a percentage such as `+1,700%`, or as `Breakout` for very large increases.

#### Trend (`trend`)

*This is an abridged preview, not a complete Dataset row.*

```json
{
  "type": "trend",
  "title": "joe buck",
  "exploreTerm": "joe buck",
  "geo": "US",
  "startedAt": "2026-10-14T00:00:00Z",
  "endedAt": null,
  "active": true,
  "searchVolume": 20000,
  "increasePercentage": 1000,
  "categories": [{ "id": 4, "name": "Entertainment" }],
  "breakdown": ["joe buck", "who is joe buck"],
  "articles": [
    {
      "title": "Michelle Beisner-Buck joined MNF long before Joe Buck made it a family affair",
      "url": "https://www.themirror.com/sport/american-football/michelle-joe-buck-mnf-family-2045760",
      "source": "The Mirror US",
      "publishedAt": "2026-10-05T11:00:00Z",
      "imageUrl": "https://encrypted-tbn2.gstatic.com/images?q=tbn:..."
    }
  ]
}
```

- `searchVolume` is a lower bound: `20000` is what the website shows as "20K+".
- `active` is `true` while the trend is still trending; `endedAt` is then `null`.
- `exploreTerm` is the form of the trend you can use as an Explore search term.
- `breakdown` lists the related searches Google groups under the trend.
- Trending Now has no category or status filter. Use `categories` and `active` to filter the results yourself.

#### Category (`category`) and location (`geo`)

```json
{
  "type": "category",
  "id": 184,
  "name": "Celebrities & Entertainment News",
  "parentId": 3,
  "path": ["Arts & Entertainment", "Celebrities & Entertainment News"],
  "depth": 2
}
```

```json
{
  "type": "geo",
  "code": "US-AL-630",
  "id": "630",
  "name": "Birmingham AL",
  "parentCode": "US-AL",
  "path": ["United States", "Alabama", "Birmingham AL"],
  "depth": 3
}
```

Rows follow Google's order, with each parent before its children. The lists start with "All categories" (`0`) and "Worldwide" (`WW`). A category that appears under more than one parent is listed once for each, with a different `path`.

#### Error rows (`error`)

When a search or result type fails, the Actor writes an error row with the settings involved and the error `message`:

```json
{
  "type": "error",
  "message": "fetch relatedQueries widget RELATED_QUERIES_1: unexpected HTTP status 400",
  "widget": "relatedQueries",
  "term": "ethereum",
  "terms": ["bitcoin", "ethereum"],
  "geo": "WW",
  "timeRange": "today 12-m",
  "category": 0,
  "property": ""
}
```

In `explore`, errors are handled per line:

- **The search fails:** the line gets one error row without a `widget` field, and the run continues with the next line.
- **A result type fails:** that result type gets an error row with its `widget` (and `term` for related queries), and the line's other result types are still saved.

The run fails only if the search fails for every line. A line whose search succeeds but whose result types all fail returns only error rows, and the run still succeeds. A successful run can therefore contain no results, so check for `error` rows rather than relying on the run status alone.

In the other modes, a failure writes one error row and fails the run. Error rows are never charged.

***

### Operational & Billing Details

#### Managed Proxies

Requests on Apify are automatically routed through managed residential proxies. You don't need any proxy setup, credentials, or a Google account. This helps keep runs from being blocked, but it can't guarantee that Google Trends is always available.

#### Pay-per-Event Billing

This Actor uses Apify's Pay Per Event (PPE) model. You pay for the results you receive, not for compute time:

- **`explore-result`:** charged once for each interest-over-time, interest-by-region, or related-queries row.
- **`trend-result`:** charged once for each Trending Now trend row.
- **`reference-list`:** charged once for each successful category or location list run, regardless of how many rows it returns.

For example, one search term with all three result types returns three `explore-result` rows. A comparison of three terms returns five: one over time, one by region, and three related queries.

What is and isn't charged:

- **Rows without data are charged.** A search with too little interest still returns its rows with empty arrays, and they count as results.
- **Error rows and invalid input are never charged.**
- **Turn off result types you don't need** to pay only for the rows you use.
- **Maximum cost per run:** If you set one, the Actor saves only the results that fit within it, then finishes successfully and logs that the maximum was reached.

Check the Actor's **Pricing** tab for current rates.

***

### Use with Apify MCP

You can run this Actor from AI assistants through Apify's hosted Model Context Protocol (MCP) server and compatible clients (such as Claude Desktop):

```text
https://mcp.apify.com?tools=crawlstone/google-trends-scraper
```

Once connected, you can ask your assistant to compare searches, check regional interest, or list what is trending.

***

### Frequently Asked Questions

#### Why do values differ between runs or from the website?

Google Trends values come from a sample of Google searches, and Google can draw a different sample each time you ask, on the website too. The Actor returns the same data the website shows for your request, so two runs with the same input can return slightly different numbers.

#### Can I compare values across different lines?

No. Google scales each line from 0 to 100 on its own, so a value of 50 in one line doesn't mean the same as 50 in another. To compare terms on one scale, put them in the same line, up to 5 terms.

#### Why did a search return empty data or an error row?

Searches with too little interest return their rows with empty arrays, as the website shows "not enough data". These rows are still charged. Some combinations are not supported by Google, such as a region resolution that doesn't fit the location, or an unknown category or location code. They return an uncharged error row. In `explore`, the run continues with your other lines, and it succeeds even if no line returns data, as long as at least one line's search went through. See **Error rows** under **Data Structure & Examples**.

#### Are duplicates removed?

No. Results keep Google's order, and duplicates stay as they are. If you enter the same line twice, you get its results twice.

#### Why is the article count limited for the past 7 days?

Over the past 7 days, Google's Trending Now lists are large enough that requesting many articles for every trend fails. The Actor therefore allows at most 3 articles per trend when **Trending period** is **Past 7 days**.

***

### Support

If you need help, open a ticket on this Actor's **Discussion** tab and include:

- Your Apify **Run ID**.
- The selected **Mode** and the **Input** you used.
- What you expected and what happened instead.

Do not share your Apify API token or other private credentials in support tickets.

# Changelog

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

# Actor input Schema

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

Choose what to collect. Only the fields used by the selected mode are read; the others are ignored.

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

Used by explore and trendingNow. Enter a Google Trends location code such as US, GB, or US-CA; run List Explore locations to see every supported code. Use WW for worldwide in explore; trendingNow does not support worldwide and rejects WW.

## `searchQueries` (type: `array`):

Required for explore. Enter 1–100 lines. Each line is one Google Trends comparison: separate up to 5 terms with commas, for example bitcoin, ethereum.

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

Used by explore. Choose a Google Trends preset, or Custom range to use the custom time range below.

## `customTimeRange` (type: `string`):

Required when Time range is Custom range, and ignored otherwise. Enter a start and end date as YYYY-MM-DD YYYY-MM-DD; the start must not be after the end.

## `category` (type: `integer`):

Used by explore. Google Trends category ID; 0 means all categories. Run List Explore categories to see every ID.

## `property` (type: `string`):

Used by explore. Choose which Google search the interest comes from.

## `includeInterestOverTime` (type: `boolean`):

Used by explore. Return one interest-over-time row per query line. Keep at least one result type enabled.

## `includeInterestByRegion` (type: `boolean`):

Used by explore. Return one interest-by-region row per query line. Keep at least one result type enabled.

## `includeRelatedQueries` (type: `boolean`):

Used by explore. Return one related-queries row per term. Keep at least one result type enabled.

## `regionResolution` (type: `string`):

Used by explore for interest by region. Leave as Google default, or choose a level; Google rejects levels that do not fit the location.

## `hours` (type: `string`):

Used by trendingNow. How far back to look for trending searches.

## `maxArticlesPerTrend` (type: `integer`):

Used by trendingNow. Number of news articles to return for each trend, 0–30. When Trending period is Past 7 days, at most 3 is allowed.

## Actor input object example

```json
{
  "mode": "explore",
  "geo": "US",
  "searchQueries": [
    "bitcoin, ethereum"
  ],
  "timeRange": "today 12-m",
  "customTimeRange": "2025-01-01 2025-06-30",
  "category": 0,
  "property": "",
  "includeInterestOverTime": true,
  "includeInterestByRegion": true,
  "includeRelatedQueries": true,
  "regionResolution": "",
  "hours": "24",
  "maxArticlesPerTrend": 3
}
```

# Actor output Schema

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

Open the default Dataset.

# 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 = {
    "mode": "explore",
    "geo": "US",
    "searchQueries": [
        "bitcoin, ethereum"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlstone/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 = {
    "mode": "explore",
    "geo": "US",
    "searchQueries": ["bitcoin, ethereum"],
}

# Run the Actor and wait for it to finish
run = client.actor("crawlstone/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 '{
  "mode": "explore",
  "geo": "US",
  "searchQueries": [
    "bitcoin, ethereum"
  ]
}' |
apify call crawlstone/google-trends-scraper --silent --output-dataset

```

## MCP server setup

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