# Google Trends Scraper: Interest, Regions, Queries (`apisamurai/google-trends-scraper`) Actor

Google Trends data that finishes: interest over time, interest by region, related queries and topics, comparisons of up to 5 terms and Trending now. Partial results are saved.

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

## Pricing

$1.00 / 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.

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: Interest, Regions, Related Queries

Get Google Trends data as clean JSON for any search term or a comparison of up to 5 terms:

- **Interest over time**: the 0 to 100 line chart, one point per minute, hour, day, week or month depending on the range, with the last unfinished point marked `isPartial`.
- **Interest by region**: countries, regions, cities or US metros, with a value per term.
- **Related queries** and **related topics**: Top and Rising, with Breakout flagged.
- **Trending now**: searches trending in a country in the past 24 hours, with search volume, start time, related queries and news articles.

Any location (worldwide, a country, a sub-region like US-CA), any time range (past hour to since 2004, or custom dates), category and search type (web, news, images, YouTube, Shopping).

### Why runs don't fail

Google rate-limits Trends hard, so other scrapers often end with nothing. This Actor is built to finish:

- Each proxy IP is its own session with its own Google cookies. When Google answers 429 or sends a page instead of data, the session waits and moves to a fresh residential IP, up to 6 attempts per request.
- At most 2 term groups run at once, with requests spaced 1 to 2 seconds apart per session.
- At the end of the run, every chart Google refused (429 or a page instead of data) gets a retry pass: after a 15 second pause, on fresh IPs with new cookies and 3 to 5 seconds between requests, with a second round after 30 seconds if needed. Charts fixed there count as delivered.
- One failing term or chart never stops the run. Everything fetched is saved as it arrives.
- The `SUMMARY` record and the run's status message list, per input line, what was saved and why anything is missing (for example "rate-limited by Google" or "search volume too low").
- The run is marked failed only if Google answered nothing at all.
- You pay only for rows saved. A chart that failed costs nothing.

### Input

| Field | What it does | Default |
| --- | --- | --- |
| `searchTerms` | One term per line, or up to 5 terms separated by commas to compare them | |
| `geo` | Country code (US), sub-region (US-CA), metro (US-CA-807), or empty for worldwide | worldwide |
| `timeRange` | `past_hour`, `past_4_hours`, `past_day`, `past_7_days`, `past_30_days`, `past_90_days`, `past_12_months`, `past_5_years`, `since_2004`, `custom` | `past_12_months` |
| `startDate`, `endDate` | YYYY-MM-DD, used with `custom`. Empty end date means today | |
| `category` | Google Trends category id (the `cat=` number in a Trends link) | 0 (all) |
| `property` | `web`, `news`, `images`, `youtube`, `shopping` | `web` |
| `interestOverTime` | Line chart per term group | on |
| `interestByRegion` | Map data per term group | on |
| `regionResolution` | `country`, `region`, `city`, `metro`. Empty uses Google's default for the location | Google default |
| `relatedQueries` | Top and rising queries per term | on |
| `relatedTopics` | Top and rising topics per term | off |
| `trendingNow`, `trendingGeo` | Trending searches of the past 24 hours for a country | off, US |
| `maxTrendingSearches` | Keep the first N trending searches in Google's order (1 to 500) | 25 |
| `proxyConfiguration` | Proxy. The country follows `geo` when you set none | Residential |

```json
{ "searchTerms": ["bitcoin", "chatgpt, gemini"], "geo": "US", "timeRange": "past_7_days" }
```

### Output

One row per term group and data type. Every row has `type`, `input`, `scrapedAt`. Field names are stable. This example is from a real run for "bitcoin", US, past 7 days, shortened:

```json
[
  {
    "type": "interestOverTime", "input": "bitcoin", "geo": "US", "timeRange": "past_7_days", "terms": ["bitcoin"],
    "points": [
      { "date": "2026-10-21T06:00:00.000Z", "values": { "bitcoin": 67 }, "isPartial": false },
      { "date": "2026-10-28T06:00:00.000Z", "values": { "bitcoin": 58 }, "isPartial": true }
    ],
    "averages": { "bitcoin": 56 }, "scrapedAt": "2026-10-28T06:04:28.275Z"
  },
  {
    "type": "interestByRegion", "input": "bitcoin", "geo": "US", "timeRange": "past_7_days", "terms": ["bitcoin"], "resolution": "region",
    "regions": [
      { "geoCode": "US-KS", "name": "Kansas", "values": { "bitcoin": 100 } },
      { "geoCode": "US-NV", "name": "Nevada", "values": { "bitcoin": 48 } }
    ],
    "scrapedAt": "2026-10-28T06:04:29.422Z"
  },
  {
    "type": "relatedQueries", "input": "bitcoin", "geo": "US", "timeRange": "past_7_days", "term": "bitcoin",
    "top": [{ "query": "bitcoin price", "value": 100 }, { "query": "bitcoin stock", "value": 19 }],
    "rising": [
      { "query": "ark invest cathie wood bitcoin forecast", "value": 55000, "isBreakout": true },
      { "query": "meta stock price", "value": 50, "isBreakout": false }
    ],
    "scrapedAt": "2026-10-28T06:04:31.928Z"
  }
]
```

Other row types:

- `relatedTopics`: like `relatedQueries`, with `topic`, `topicType` and `topicId` instead of `query`.
- `trendingNow`: `geo`, `title`, `trafficApprox` (searches, a lower bound as Google shows it, e.g. 200000 for "200K+"), `startedAt`, `relatedQueries` (list of strings), `newsArticles` \[{ `title`, `url`, `source` }].

Dates are UTC. Rising `value` is the growth in percent. In a comparison, region values show each term's share in that region.

### Pricing

$1 per 1,000 results. One result is one dataset row: one chart for one term group, one related list for one term, or one trending search. Nothing is charged for data that could not be fetched. Set a maximum cost per run and the Actor stops cleanly when it is reached.

### FAQ

**Why are the values between 0 and 100?**
Google Trends never shows absolute search counts. Values are relative: 100 is the peak for the chosen terms, location and time, 50 is half as popular, 0 means not enough data. Terms on one line share one scale, so put terms on the same line to compare them.

**What happens when Google rate-limits?**
The request is retried from a fresh residential IP with new cookies, up to 6 times. If a chart still fails, the rest of the run continues and the chart gets up to 2 more slow retry rounds at the end of the run. Only charts that fail those too are listed as missing in the `SUMMARY` record, with the reason. Re-run just that term later.

**Do I need a proxy?**
Residential proxy is the default and works best. Without a proxy the Actor still runs but cannot change IP, so it retries less (3 attempts) and waits longer between tries.

**Can I schedule it?**
Yes. Use Apify Schedules to run it daily or weekly and track a term over time. With Trending now on, a daily schedule gives you a log of what was trending in a country.

**Why is a chart missing for my term?**
Google returns no data when search volume is too low for the chosen location and range, or does not offer some charts for some settings (for example metro level outside the US). The `SUMMARY` record gives the reason per term.

**Is scraping Google Trends legal?**
The Actor reads the same public, logged-out data anyone sees on trends.google.com. It does not log in or collect personal data. You are responsible for how you use the data and for following the laws and terms that apply to you. If in doubt, ask a lawyer.

### Integrations

Results are in an Apify dataset you can download as JSON, CSV or Excel, or read through the Apify API. Connect the Actor to Make, Zapier, n8n, Google Sheets, Slack or webhooks through Apify integrations to send new trend data where you need it.

# Actor input Schema

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

One term per line. To compare terms on the same 0 to 100 scale, put up to 5 on one line separated by commas, e.g. chatgpt, gemini.

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

Country code (US, DE, GB), sub-region (US-CA) or metro (US-CA-807). Leave empty for worldwide.

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

Period to look at. Choose Custom to use the start and end dates below.

## `startDate` (type: `string`):

First day, YYYY-MM-DD, from 2004-01-01. Used when Time range is Custom.

## `endDate` (type: `string`):

Last day, YYYY-MM-DD. Empty means today. Used when Time range is Custom.

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

Google Trends category id, e.g. 0 all categories, 7 Finance, 5 Computers and Electronics. The number appears as cat= in a Trends link.

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

Which Google search to measure.

## `interestOverTime` (type: `boolean`):

The 0 to 100 line chart for each term or comparison.

## `interestByRegion` (type: `boolean`):

The 0 to 100 value for each country, region, city or metro.

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

Level for Interest by region. Empty uses the Google default: countries for worldwide, regions inside a country. Region, city and metro need a country in Location; metro works only for the US.

## `relatedQueries` (type: `boolean`):

Top and rising searches related to each term.

## `relatedTopics` (type: `boolean`):

Top and rising topics related to each term.

## `trendingNow` (type: `boolean`):

Searches trending in the past 24 hours in a country, with search volume, start time, related queries and news articles. Works with or without search terms.

## `trendingGeo` (type: `string`):

Country code, e.g. US, GB, IN. Empty uses the country of Location, or US.

## `maxTrendingSearches` (type: `integer`):

Keep only the first N trending searches, in the order Google lists them. Each one is a result.

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

Google rate-limits Trends hard. Residential proxies work best; the proxy country follows Location when you set none.

## Actor input object example

```json
{
  "searchTerms": [
    "bitcoin",
    "chatgpt, gemini"
  ],
  "geo": "",
  "timeRange": "past_12_months",
  "category": 0,
  "property": "web",
  "interestOverTime": true,
  "interestByRegion": true,
  "relatedQueries": true,
  "relatedTopics": false,
  "trendingNow": false,
  "maxTrendingSearches": 25,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "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 = {
    "searchTerms": [
        "bitcoin",
        "chatgpt, gemini"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

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

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

```

## MCP server setup

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