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

Google Trends scraper and API, no browser. Interest over time, interest by region and city, related queries and topics. Compare unlimited keywords on one scale (Google caps at 5). Same fields as the official scraper, faster and cheaper. $1.49 per 1,000.

- **URL**: https://apify.com/reportable\_broth/google-trends-scraper.md
- **Developed by:** [Quiet Harvest](https://apify.com/reportable_broth) (community)
- **Categories:** SEO tools, Marketing, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.09 / 1,000 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

Get Google Trends data without a browser: interest over time, interest by country, region or US metro area, and top and rising related searches, for any keyword, region, time range, category and search type (web, news, images, YouTube, Shopping). It also does something Google Trends itself can't: **compare any number of keywords on one scale.**

**$1.49 per 1,000 results.** Paid plans pay less, down to $0.09 per 1,000 (see Pricing).

***

### Why this one

**It doesn't time out.** There is no browser. Each keyword takes a few HTTP requests, so 60 keywords finish in about a minute on 256 MB of memory.

**It gets past Google's rate limit.** Google Trends answers 429 to anyone without a Google cookie, and it blocks an IP after about a hundred requests. Each keyword here gets its own IP and a fresh cookie. If Google pushes back, the Actor switches both and tries again.

**Unlimited keywords on one scale (no other scraper does this).** Google compares at most 5 terms per chart and rescales every chart so its own peak is 100, so a "40" in one chart and a "40" in another mean different things. Turn on **Compare ALL terms on one scale** and give it 12, 50 or 200 keywords. The Actor chains the charts through a shared anchor term and returns every keyword on one 0–100 scale, ranked by average interest. Use it for brand share of search, product research or picking content topics.

**Drop-in field names.** Output uses the same field names as the official Apify Google Trends Scraper (`interestOverTime_timelineData`, `relatedQueries_top`, `relatedQueries_rising`...). There are also simpler fields: `interestOverTime` as a list of `{date, value}` points, plus `averageInterest`, `peakInterest`, `peakDate` and `latestInterest`.

***

### Quick start

```json
{
  "searchTerms": ["bitcoin", "ethereum"],
  "geo": "US",
  "timeRange": "today 12-m"
}
```

Several terms on the same chart (up to 5, like on the website):

```json
{ "searchTerms": ["nike, adidas, puma"], "isMultiple": true }
```

Rank 12 brands on one scale:

```json
{
  "searchTerms": ["nike", "adidas", "puma", "new balance", "asics", "reebok", "under armour", "skechers", "vans", "converse", "fila", "hoka"],
  "compareAllTerms": true,
  "anchorTerm": "puma"
}
```

Or paste links from the website:

```json
{ "startUrls": ["https://trends.google.com/trends/explore?date=now%207-d&geo=US&q=earthquake"] }
```

### Output

One item per keyword:

| Field | Notes |
|---|---|
| `searchTerm`, `inputUrlOrTerm` | |
| `geo`, `timeRange`, `category`, `searchType` | What was searched |
| `interestOverTime` | `[{date, formattedTime, value, isPartial}]`. `date` is ISO 8601 UTC. `isPartial` marks the period still in progress |
| `averageInterest`, `peakInterest`, `peakDate`, `latestInterest` | Calculated from complete periods only |
| `hasData` | `false` when Google has too little search volume to show anything |
| `interestOverTime_timelineData`, `interestOverTime_averages` | Google's raw format, same as the official scraper |
| `interestBy` | `[{geoCode, geoName, value}]`, highest first. Countries for worldwide searches, regions or states for a country, metro areas with `DMA` |
| `relatedQueries_top`, `relatedQueries_rising` | `[{query, value, formattedValue, link}]`. Rising values like `+4,750%` or `Breakout` |
| `comparedWith` | The other terms on the same chart |
| `trendsUrl` | Open the same view on Google Trends |

With **Compare ALL terms on one scale**, you also get `rank`, `anchorTerm`, `normalizedAcrossAllTerms: true`, and `lowPrecision`. `lowPrecision` is `true` when a term is so much smaller than the anchor that most of its points round to 0; if you see it, pick a smaller anchor.

Example (shortened):

```json
{
  "searchTerm": "bitcoin",
  "geo": "Worldwide",
  "timeRange": "today 12-m",
  "averageInterest": 44.92,
  "peakInterest": 100,
  "peakDate": "2026-02-01T00:00:00Z",
  "interestOverTime": [{"date": "2025-09-21T00:00:00Z", "value": 43, "isPartial": false}],
  "interestBy": [{"geoCode": "CH", "geoName": "Switzerland", "value": 100}, {"geoCode": "AT", "geoName": "Austria", "value": 88}],
  "relatedQueries_rising": [{"query": "how to buy bitcoin safely", "formattedValue": "Breakout"}]
}
```

### Input

| Field | Default | |
|---|---|---|
| `searchTerms` | | One keyword per line |
| `isMultiple` | false | Split a line on commas and compare those terms on one chart (5 max per chart) |
| `compareAllTerms` | false | Put every keyword on one scale, no limit |
| `anchorTerm` | first term | Shared term for Compare ALL. Pick one of medium popularity |
| `startUrls` | | Google Trends explore links |
| `timeRange` | Past 12 months | Past hour, 4 hours, day, 7 days, 30 days, 90 days, 12 months, 5 years, or since 2004 |
| `customTimeRange` | | `2024-01-01 2024-06-30`; overrides Time range |
| `geo` | worldwide | `US`, `GB`, `JP`, `TW`, or a region such as `US-CA` |
| `category` | 0 | The number from `cat=` in a Trends URL |
| `searchType` | web | web, images, news, youtube, shopping |
| `includeInterestByRegion`, `includeRelatedQueries` | true | Turn these off for a faster run |
| `regionResolution` | Automatic | Country, Region / state, or Metro (US DMA) |
| `language` | en-US | Language of dates and region names |

### Pricing

Pay per result (one keyword = one result):

| Plan | Free | Bronze | Silver | Gold | Platinum | Diamond |
|---|---|---|---|---|---|---|
| Per 1,000 results | $1.49 | $0.79 | $0.39 | $0.09 | $0.09 | $0.09 |

That's less than the official Google Trends Scraper on every plan.

### Good to know

- **Related topics and city-level data are not included.** Google now serves these only to its own website, behind a bot check. Related *queries* and country, region and metro data work normally.
- Google Trends numbers are sampled. The same search run twice can differ by a few points, on the website too. Peaks and rankings stay the same.
- Values are relative (0–100), not search counts. 100 is the peak within the chart, or within all terms when you use Compare ALL.

### Questions

Found a bug or want a field added? Open an issue on the Issues tab.

# Actor input Schema

## `searchTerms` (type: `array`):

One term per line. Each line gets its own result. Turn on 'Compare terms in one line' to put comma-separated terms on the same chart.

## `isMultiple` (type: `boolean`):

Treat commas as separators: 'nike, adidas, puma' is compared on one chart (up to 5 per chart, the Google Trends limit).

## `compareAllTerms` (type: `boolean`):

Google Trends only compares 5 terms at a time and rescales every chart to its own peak, so numbers from different charts can't be compared. This chains the charts through a shared anchor term and puts every term on one 0-100 scale, ranked by average interest. Returns interest over time only.

## `anchorTerm` (type: `string`):

The term shared by every chart. Pick one of mid popularity. Default: the first search term.

## `startUrls` (type: `array`):

Paste explore URLs from trends.google.com. Terms, region, time range, category and search type are taken from the URL.

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

Preset time range.

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

Overrides Time range. Format: 2024-01-01 2024-06-30

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

Empty for worldwide, a country code (US, GB, JP, TW) or a region code (US-CA, GB-ENG).

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

0 = all categories. Take the number from the cat= part of a Trends URL (e.g. 7 = Finance, 71 = Food & Drink).

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

Which Google search the interest comes from.

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

Countries, states or cities where the term is most popular.

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

Automatic = countries for worldwide, regions/states for a country. Metro areas (DMA) work for the US.

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

Top and rising searches related to the term.

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

Language of topic names and dates, e.g. en-US, de, ja, zh-TW.

## `maxConcurrency` (type: `integer`):

How many terms to fetch at the same time.

## `proxyConfiguration` (type: `object`):

Every search uses a fresh IP and a fresh Google cookie.

## Actor input object example

```json
{
  "searchTerms": [
    "bitcoin",
    "ethereum"
  ],
  "isMultiple": false,
  "compareAllTerms": false,
  "startUrls": [],
  "timeRange": "today 12-m",
  "geo": "",
  "category": 0,
  "searchType": "web",
  "includeInterestByRegion": true,
  "regionResolution": "AUTO",
  "includeRelatedQueries": true,
  "language": "en-US",
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (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 = {
    "searchTerms": [
        "bitcoin",
        "ethereum"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("reportable_broth/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 = {
    "searchTerms": [
        "bitcoin",
        "ethereum",
    ],
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("reportable_broth/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 '{
  "searchTerms": [
    "bitcoin",
    "ethereum"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call reportable_broth/google-trends-scraper --silent --output-dataset

```

## MCP server setup

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