# Google Trends Scraper — Reliable, Never Charges for Empty Runs (`0xgollum/reliable-trends-scraper`) Actor

Pulls Google Trends interest-over-time and related queries for your keywords. Built around one rule: if a keyword comes back empty after retrying across multiple residential-proxy sessions, it is logged as a failure and skipped - never billed. No more paying for runs that silently return nothing.

- **URL**: https://apify.com/0xgollum/reliable-trends-scraper.md
- **Developed by:** [0xGollum](https://apify.com/0xgollum) (community)
- **Categories:** Automation, SEO tools
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 trend 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/platform/actors/running/actors-in-store#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

## Reliable Trends Scraper

Every other Google Trends scraper on the Store shares the same complaint in its reviews: *"ran for 20 minutes, didn't return anything"*, *"took my money for zero results"*. That's not a Google Trends limitation — it's what happens when a scraper doesn't handle rate-limiting and IP blocking properly, and bills you anyway.

This one is built around a single rule: **a keyword is only ever billed if it actually returned real data.** If Google blocks every attempt, you get a clear line in the run log explaining why — not a silent empty row you paid for.

### How the reliability actually works

- **Residential proxy by default.** Google Trends aggressively blocks datacenter IPs — this is the #1 root cause of empty/blocked runs on other scrapers. Every request goes out through Apify's residential proxy pool.
- **Session rotation, not just retries.** If one proxy identity gets rate-limited, the actor doesn't just retry on the same IP — it opens a fresh proxy session (new IP, fresh cookies) and tries again, up to `max_proxy_sessions` times per keyword.
- **Exponential backoff with jitter** inside each session, so retries don't hammer Google in a tight loop (which is itself a fast way to get blocked harder).
- **Silent-empty detection.** A 200 OK with a technically-valid but content-free response is treated as a failure, not a success — the exact failure mode the incumbent's bad reviews describe.
- **No charge on failure.** A keyword that fails every session/retry is logged as a warning and simply not pushed to the dataset — you are not billed for it.

### Input

- `keywords` (required): search terms to check
- `geo` (optional, default worldwide): 2-letter country code, e.g. `US`, `FR`
- `timeframe` (optional, default "Past 3 months"): `now 7-d`, `today 1-m`, `today 3-m`, `today 12-m`, `today 5-y`
- `category` (optional, default 0 = all categories): Google Trends category ID
- `include_related_queries` (optional, default true): also fetch top/rising related queries
- `max_proxy_sessions` (optional, default 3, max 6): how many fresh proxy identities to try per keyword before giving up on it
- `proxyConfiguration` (optional, default: Apify residential proxy): can be overridden, but a datacenter/no proxy will get blocked far more often — expect a lower success rate if you turn it off

### Output (one row per keyword that returned real data)

```json
{
  "keyword": "bitcoin",
  "geo": "US",
  "timeframe": "today 3-m",
  "data_points": 93,
  "latest_value": 29,
  "peak_value": 100,
  "average_value": 51.2,
  "top_related_query": "bitcoin price",
  "top_rising_query": "spacex stock price",
  "timeline": [{"date": "May 15, 2026", "value": 50}, "..."],
  "related_top": [{"query": "bitcoin price", "value": 100}, "..."],
  "related_rising": [{"query": "spacex stock price", "value": 38850}, "..."]
}
```

Values follow Google's own 0-100 relative-interest scale. `timeline`/`related_top`/`related_rising` carry the full data; the flat fields above them are a quick-glance summary for the dataset table view.

### Known limitation — read before you buy

Google Trends' internal API is unofficial and can change shape without notice — true of every scraper in this category, not specific to this one. What's different here is what happens when it does: a keyword that stops working gets skipped and logged, not billed as if it succeeded.

### Pricing

Pay per result — no charge for keywords that come back empty.

# Actor input Schema

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

Search terms to pull Google Trends interest data for.

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

2-letter country code (e.g. US, FR, GB). Leave empty for worldwide.

## `timeframe` (type: `string`):

Time range for the interest-over-time data.

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

Google Trends category ID to restrict the search to. 0 = all categories.

## `include_related_queries` (type: `boolean`):

Also fetch top and rising related queries for each keyword.

## `max_proxy_sessions` (type: `integer`):

If Google blocks/rate-limits one proxy identity, retry with a fresh one, up to this many times, before giving up on a keyword (and not charging for it).

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

Residential proxy strongly recommended - Google Trends aggressively blocks datacenter IPs, which is the #1 cause of empty/failed runs on other scrapers.

## Actor input object example

```json
{
  "keywords": [
    "bitcoin",
    "electric car"
  ],
  "geo": "",
  "timeframe": "today 3-m",
  "category": 0,
  "include_related_queries": true,
  "max_proxy_sessions": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "keywords": [
        "bitcoin",
        "electric car"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("0xgollum/reliable-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 = { "keywords": [
        "bitcoin",
        "electric car",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("0xgollum/reliable-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 '{
  "keywords": [
    "bitcoin",
    "electric car"
  ]
}' |
apify call 0xgollum/reliable-trends-scraper --silent --output-dataset

```

## MCP server setup

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