Google Trends Scraper & API: Interest, Related, Trending avatar

Google Trends Scraper & API: Interest, Related, Trending

Pricing

from $1.50 / 1,000 results

Go to Apify Store
Google Trends Scraper & API: Interest, Related, Trending

Google Trends Scraper & API: Interest, Related, Trending

Reliable Google Trends data: interest over time, interest by region, related queries and topics, and Trending Now. Pay-per-event, no browser, partial results still succeed.

Pricing

from $1.50 / 1,000 results

Rating

0.0

(0)

Developer

Sunburst

Sunburst

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

13 hours ago

Last modified

Share

Get Google Trends data (interest over time, interest by region, related queries and topics, and Trending Now) as clean JSON or CSV, without a browser. It talks to the same public JSON endpoints the Trends website uses. There is no browser, so there is no page-load timeout to abort the run.

Built to be a drop-in alternative to existing Store Actors: the familiar searchTerms, isMultiple, timeRange, geo, category, and startUrls fields still work. Failed widgets become error rows. The run still finishes SUCCEEDED.

Why this Actor

Google Trends does not offer a public official API. The old Python library most tutorials recommend, pytrends, is archived. Browser-based scrapers stall on 429s and timeouts. This Actor is the opposite of that:

  • Direct endpoints. GET /trends/api/explore for tokens, then one widgetdata call per chart. Trending Now uses the current batchexecute RPC (i0OFE), with the public RSS feed as fallback.
  • Retries that do not kill the run. Exponential backoff with jitter, NID cookie warmup, request pacing, and per-widget retry. A missing related-topics block does not throw away the timeline you already paid to fetch.
  • Cheap to run. No Chromium. Default 512 MB. Uses the automatic Apify Proxy. You are billed $0.02 per run and $0.0015 per successful dataset row. Failed items are free.
  • Store-test friendly. The default input (bitcoin, US, past 12 months) returns non-empty interest-over-time and related-queries rows in seconds.

What you get

Data typeGoogle Trends UINotes
Interest over timeExplore chartMinute / day / week / month granularity follows the time range
Interest by regionInterest by subregion / city / metroresolution: COUNTRY, REGION, CITY, DMA
Related queriesTop and risingReturned in Google's own objects. Rising queries are decoy-filtered by default (see Rising queries and decoys)
Related topicsTop and risingRequested; Google often returns an empty list to scripted clients
Trending Nowtrending.google.com/trendingCountry + 4h / 24h / 48h / 7d window

Compare up to 5 terms per request. Many terms are batched automatically.

Input

Default (daily Store test)

{
"searchTerms": ["bitcoin"],
"timeRange": "today 12-m",
"geo": "US",
"property": "web",
"dataTypes": ["TIMESERIES", "GEO", "RELATED_QUERIES"],
"outputMode": "perDataType"
}

Compare terms on one scale

{
"searchTerms": ["openai, anthropic, google gemini"],
"isMultiple": true,
"timeRange": "today 3-m",
"geo": "US",
"property": "youtube"
}
{
"startUrls": [
{ "url": "https://trends.google.com/trends/explore?q=electric%20bike&geo=DE&date=today%2012-m" }
]
}
{
"fetchTrendingNow": true,
"trendingSearchesCountry": "US",
"trendingSearchesTimeframe": "24",
"trendingSearchesMaxItems": 50
}

Familiar fields (drop-in)

FieldWhat it does
searchTermsList of keywords. Required unless you use URLs, a sheet, or Trending Now.
isMultipleTreat commas as comparison separators (max 5 per group).
timeRangenow 1-H, now 4-H, now 1-d, now 7-d, today 1-m, today 3-m, today 12-m, today 5-y, all.
customTimeRangeYYYY-MM-DD YYYY-MM-DD, overrides timeRange.
geoCountry or region code. Empty = worldwide.
categoryNumeric Trends category id. Empty = all.
property / gpropweb, news, images, youtube, froogle (Shopping).
startUrlsExplore URLs; q / geo / date / cat / gprop win per URL.
spreadsheetIdPublic Google Sheet, first column, row 1 is the header.
viewedFromInterface language (en-US).
maxItems, maxConcurrency, maxRequestRetriesAccepted. Concurrency defaults to 1 on purpose.
skipDebugScreen, pageLoadTimeoutSecsAccepted and ignored (no browser).

Extra fields this Actor adds

FieldDefaultWhat it does
dataTypesinterest over time, region, related queriesAlso RELATED_TOPICS, TRENDING_NOW.
resolutionAutoCOUNTRY, REGION, CITY, DMA.
outputModeperDataTypecombined for one nested row per term; flat for CSV.
risingFilterstrictstrict, balanced, or off. Filters decoy rising queries. See Rising queries and decoys.
fetchTrendingNowfalseDaily / real-time trending list.
requestDelayMs350Pacing between Google calls.
proxyConfigurationAutomatic Apify Proxy (useApifyProxy: true)See Proxy.

Output

perDataType (default) — one clean dataset row per term per widget:

{
"dataType": "interest_over_time",
"status": "ok",
"searchTerm": "bitcoin",
"searchTerms": ["bitcoin"],
"geo": "US",
"timeRange": "today 12-m",
"property": "web",
"itemCount": 53,
"timeline": [{ "time": "1761436800", "value": [32], "formattedAxisTime": "Oct 26, 2025" }],
"trendsUrl": "https://trends.google.com/trends/explore?q=bitcoin&geo=US"
}

combined — one nested row per term, with the field names other Store Actors already emit:

interestOverTime_timelineData, interestOverTime_averages, interestBy / interestBySubregion / interestByCity / interestByMetro, relatedQueries_top, relatedQueries_rising, relatedTopics_top, relatedTopics_rising.

flat — one row per time point, region, or related item. Easy to open in Google Sheets. Billed per row, so a 5-year weekly series costs more than perDataType.

Error rows look like this and are not charged:

{
"dataType": "related_topics",
"status": "error",
"errorCode": "NO_DATA",
"error": "related_topics_empty: Google returned an empty rankedList for RELATED_TOPICS.",
"searchTerm": "bitcoin"
}

Pricing

Pay-per-event. You are not billed for platform compute on top of the event prices (standard PPE). Failed items are free.

EventPriceWhen
apify-actor-start$0.00005Once per run (Apify platform start event)
run-start$0.02Once per run
result$0.0015Each successful dataset row

A typical one-keyword explore (timeline + region + related queries) is about $0.0246. See PRICING.md for compute/proxy cost and margin.

Set a max total charge on the run if you want the Actor to stop cleanly instead of overrunning a budget.

Proxy

Default: automatic Apify Proxy (useApifyProxy: true, no group selected). It works on all Apify plans, including Free, and was sufficient for Trends JSON in our test runs with paced requests.

The GOOGLE_SERP group is not the default. Apify documents it as HTTP-only access to www.google.com Search and Shopping. It cannot fetch trends.google.com. If you select it (or any group your plan cannot access), the Actor falls back to the automatic Apify Proxy, then to direct egress.

Residential proxies work and cost much more. Use them only if 429s persist after retries.

Locally, or on the platform without a proxy password, the Actor runs direct. From a clean VM that is enough for paced requests.

Reliability notes

  1. Cookie warmup on trends.google.com to collect an NID.
  2. GET explore (POST explore returned HTTP 500 in live checks).
  3. One widget call at a time, retried on 429 / 5xx with jittered backoff and proxy rotation.
  4. Partial success is still success. The dataset always has a row you can filter on status.
  5. Related topics are requested and often empty. That is a Google-side gap, not a timeout. Related queries still arrive.

Live test results (Apify platform, Oct 31, 2026, automatic Apify Proxy): 16 of 16 runs succeeded, including the default input, keyword comparison, interest by region, and related queries. Run times ranged from 2.3 s to 15.2 s. The default input finished in 6.4 s with 3 result rows.

Rising queries and decoys

Google labels every scripted Trends session USER_TYPE_SCRAPER (you can see it in the explore response as userConfig.userType). The widget token is signed over that label, so it cannot be changed: an edited request gets HTTP 401. Other Actors report the same label on residential IPs and in a real headless Chrome.

For sessions with that label, Google mixes decoy queries into the rising list of every keyword. They are generic phrases unrelated to your keyword, like "pet care tips", "how to cook pasta", "walmart near me", or "cheap flights 2024". Top queries, timelines, and regions match what a browser shows. This is not a parsing bug: the decoys are in Google's raw relatedsearches response.

Every related-queries row now includes:

  • googleUserType: the label Google put on the session.
  • dataQualityWarning: a plain-language warning when the label is USER_TYPE_SCRAPER.
  • risingFilter: the filter mode used.
  • rising: the rising queries that passed the filter.
  • suspectedDecoys: removed entries, each with decoyReasons (knownDecoy, repeatedAcrossKeywords, unrelatedToKeyword). Nothing is deleted.

risingFilter modes:

ModeWhat it does
strict (default)Moves an entry if it is a known decoy, if it was rising for an unrelated keyword earlier in the same run, or if it shares no meaningful word with the keyword or its top queries.
balancedMoves only known decoys and cross-keyword repeats. Unrelated entries stay in rising with "unverified": true. Good for celebrity and news keywords, where real rising terms often share no words with the keyword.
offGoogle's raw rising list.

An entry that contains your keyword is never treated as a known decoy, so pasta still gets "how to cook pasta". In flat mode, decoy rows are left out, which means they are not billed, and a note gives the count. Treat rising queries as directional. Top queries are the more reliable list.

Live example (coffee, US, past 12 months, Oct 31, 2026): Google returned 25 rising queries. strict kept 8 that mention coffee and moved 17, including "pet care tips", "learn programming", and "best laptops 2025".

This is not a teardown of anyone else's work. It is a checklist of what to look for:

This ActorBrowser-based scrapersLightweight keyword/trending Actors
How it fetchesPublic JSON endpointsHeadless ChromeMixed
Typical failure modeEmpty related-topics listTimeouts, aborts, 429sMissing widgets
Compare 5 termsYesYesSometimes one keyword
Trending NowCurrent RPC + RSS fallbackPage scrapeOften the main product
Default outputOne row per data typeOne nested rowCustom shapes
You pay$0.02 + $0.0015/rowEvents and browser computeSimilar PPE, usually higher

If you already have a Make/Zapier/API task pointed at another Actor, start with outputMode: "combined" and the same searchTerms / timeRange / geo. Then switch to perDataType if you want cleaner billing.

FAQ

Is there an official Google Trends API? Google has announced a limited official API with access by application. This Actor reads the public Trends website endpoints that any logged-out browser already calls.

Are the numbers search volumes? No. 100 is the peak within the selected terms, geo, and time range. Use Trending Now's searchVolume field for Google's trending-bucket estimate, not for SEO volume.

Is scraping Google Trends legal? You get publicly visible data. You are responsible for how you use it. Review Google's Terms of Service and your local law before large jobs.

Why did rising queries include unrelated things like "how to cook pasta"? Google adds them on purpose for automated sessions. See Rising queries and decoys. The default risingFilter: "strict" moves them to suspectedDecoys.

Why are related topics empty? Google often returns rankedList: [] for the RELATED_TOPICS widget to non-browser clients. The Actor still records an uncharged error row so you can see it. Related queries are populated.

Will the daily default input stay green? Yes, that is a design constraint. bitcoin + US + past 12 months + three widgets is well under 5 minutes and returns non-empty rows.

Can I run it locally?

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements-dev.txt
# uses storage/key_value_stores/default/INPUT.json
python -m src
pytest
GOOGLE_TRENDS_LIVE_TEST=1 pytest tests/test_live.py

More actors from this developer

Develop and publish

See PUBLISHING.md for Docker build and apify push steps. You do not need Apify credentials to run the unit tests or the live smoke against Google.

Changelog

See CHANGELOG.md.