Google Trends Scraper — Interest, Regions, Queries & Topics
Pricing
from $2.00 / 1,000 search terms
Google Trends Scraper — Interest, Regions, Queries & Topics
Google Trends interest over time, interest by region and top/rising related queries and topics for any keyword, from the site's own JSON API — no browser. Warms the session cookie and rotates IPs on HTTP 429, so runs finish instead of timing out.
Pricing
from $2.00 / 1,000 search terms
Rating
0.0
(0)
Developer
DIOPSIDE AI
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
2
Monthly active users
7 days ago
Last modified
Share
Google Trends Scraper — interest over time, by region, related queries & topics
Drop-in compatible with apify/google-trends-scraper — same input fields, same billing unit, lower
price, and it finishes. Search-interest data straight from Google Trends' own JSON API: how interest
in a keyword moved over time, where it is strongest, and which queries and topics are rising alongside
it. No API key, no browser, no Google account.
One run gives you every panel you see on trends.google.com/trends/explore:
| Panel | record_type | Typical size (1 term, 12 months, US) |
|---|---|---|
| Interest over time | interest_over_time | 53 weekly points |
| Interest by region | interest_by_region | 51 US states |
| Related queries (top & rising) | related_query | 25 top + 25 rising |
| Related topics (top & rising) | related_topic | 25 top + ~10 rising |
Related topics come back as entities, not strings — topic_mid (/m/05p0rrx), topic_type
(Cryptocurrency) and a title — so they survive spelling variants and translation, which is the whole
reason to prefer them over related queries.
Why this one
Google Trends rate-limits hard, and that is where the other scrapers in this category lose runs. Two things trigger an HTTP 429, and this actor handles both:
- A session with no Google cookie is 429'd on its very first call. Touching a Trends page once
sets the
NIDcookie Google requires; every call on that session then succeeds. This actor warms each HTTP session before it asks for data, and re-warms after every IP change. - One IP has a request budget. Steady traffic burns it in about a minute, and Google then answers 429 to everything from that IP until it cools down. Instead of retrying the dead IP — or hanging until the platform timeout — this actor climbs a proxy ladder: fresh IP in your proxy tier, then again, then Apify RESIDENTIAL. Every new IP gets its own sticky proxy session and its own warmup, so one IP keeps one cookie jar. The run reports which tier it finished on.
It also runs without a browser. The leading actor in this category drives a headless Chrome at 4096 MB; this one talks to the same JSON API Google's own page calls, in 1024 MB, so a one-term run finishes in ~12s of platform time instead of ~36s — which is most of why the per-term price is lower.
Related topics without a browser. Google classifies the session that asks for a widget token and
writes the verdict into the token itself (userConfig.userType). A token minted by /trends/api/explore
is stamped USER_TYPE_SCRAPER, and Google answers the related-topics route for such a token with an
empty list — while answering related queries in full from the very same token, seconds apart. The
browser-based actors in this category get the panel because they render Google's embed widget, whose
token is stamped USER_TYPE_EMBED. This actor fetches that embed token directly — one extra HTML
request, no Chrome, no 4 GB — so you get the panel at the API path's speed and price. If a related
panel ever comes back empty from the explore token, the embed token is tried automatically, so the
same fallback covers related queries if Google ever withholds those too.
Everything else is built the same way. Widget tokens, comparison layouts and request bodies are
discovered at run time — the actor replays Google's own explore response rather than
constructing requests from hardcoded templates, so a layout change upstream does not break it. A
panel Google has no data for answers 204 No Content; that is treated as an answer (zero records
plus a note in the status message), not as an error worth retrying on four more IPs. Missing values
are null.
Input
| Field | Type | Default | Notes |
|---|---|---|---|
searchTerms | string[] | — | Required. One set of results per term. |
timeRange | string | today 12-m | Google's own codes: "" (default), now 1-H, now 4-H, now 1-d, now 7-d, today 1-m, today 3-m, today 12-m, today 5-y, all. |
customTimeRange | string | "" | 2024-01-01 2024-12-31. Overrides timeRange. |
geo | string | "" (worldwide) | US, GB, US-NY, AU-NSW, US-NY-501. |
searchType | string | Web Search | Web Search, Image Search, News Search, Google Shopping, YouTube Search. |
category | string | "" | Google Trends category id as a string, same list as the other actors: "7" Finance, "16" News, "71" Food, "174" Sports… "" = all. |
categoryId | integer | 0 | Any category id, including the ~1400 sub-categories the list above does not show (1138 Cryptocurrency). Overrides category. |
outputs | string[] | all four | interestOverTime, interestByRegion, relatedQueries, relatedTopics. Billing is per search term, so extra panels are free. |
geoResolution | string | auto | COUNTRY, REGION, CITY, DMA for the region panel. |
isMultiple | boolean | false | true scores terms against each other in groups of five, like the compare view. |
language | string | en-US | Affects region names and formatted labels. |
maxItems | integer | 0 | Hard cap on records, and therefore on cost. |
proxyConfiguration | object | Apify proxy | The tier tried first. |
residentialFallback | boolean | true | Allow escalation to Apify RESIDENTIAL when a tier keeps getting 429. |
Switching from apify/google-trends-scraper
Change the actor id. searchTerms, isMultiple, timeRange, customTimeRange, geo, category
and maxItems keep their names, types and allowed values — including timeRange: "" and the string
category ids — so an input written for that actor runs here unchanged. Fields it has that we do not
(maxConcurrency, maxRequestRetries, pageLoadTimeoutSecs, skipDebugScreen) are browser-tuning
knobs; this actor talks to Google's JSON API directly and does not need them.
The output is deliberately different: that actor returns one dataset item per search term with
every panel nested inside (interestOverTime_timelineData, interestBySubregion, relatedTopics_top
…). This one returns flat rows — one per data point, tagged with record_type — which is what you
want for a warehouse load, a CSV, or a filter on one panel. The billing unit is the same either way:
one charge per search term.
Output
One flat record per data point. record_type tells you which panel it came from; fields that do not
apply to a record type are null. The dataset ships with four views (all records, interest over
time, interest by region, related) so the console and CSV exports stay readable.
{"record_type": "interest_over_time","search_term": "bitcoin","geo": "US","time_range": "today 12-m","search_type": "Web Search","category": 0,"language": "en-US","is_comparison": false,"date": "2026-03-15","time_utc": "2026-03-15T00:00:00Z","timestamp": 1773532800,"formatted_time": "Mar 15 - 21, 2026","value": 74,"formatted_value": "74","is_partial": false,"scraped_at": "2026-09-18T12:00:00Z"}
{"record_type": "related_query","search_term": "bitcoin","rank_list": "rising","rank": 1,"query": "how to buy bitcoin safely","value": 17000,"formatted_value": "Breakout","link": "https://trends.google.com/trends/explore?q=how+to+buy+bitcoin+safely&date=today+12-m&geo=US"}
{"record_type": "related_topic","search_term": "bitcoin","rank_list": "top","rank": 1,"query": "Bitcoin","topic_mid": "/m/05p0rrx","topic_type": "Cryptocurrency","value": 100,"formatted_value": "100","link": "https://trends.google.com/trends/explore?q=/m/05p0rrx&date=today+12-m&geo=US"}
Two details worth knowing, because they change how the numbers should be read:
valueis Google's 0-100 index, relative to the peak within that query. Two separate runs are not comparable; useisMultiplewhen you need terms on one scale.is_partialistrueon the final time bucket, which is still filling up. Averaging it in without noticing shows a fake drop at the end of every chart.- On rising related queries and topics
valueis a percentage increase, and Google labels anything enormous asBreakoutinformatted_value. - Related topics carry
topic_midandtopic_type; related queries carry neither and leave themnull. Both put a human-readable label inquery, so one column works for both.
Sizes and cost
You are billed per search term, not per record. One term that returns 53 weekly points, 51 states and 50 related queries and 35 related topics is one charge — the same charge as a term you asked a single panel for. Ask for every panel and the longest range; the price does not move. A term Google has no data for is free.
| Query | Records | Billed |
|---|---|---|
| 1 term, 12 months, US, default panels | ~190 | 1 term |
| 1 term, 5 years, worldwide, default panels | ~600 | 1 term |
| 100 terms, 12 months, US, default panels | ~19,000 | 100 terms |
| 3 terms compared, 90 days, GB | 291 | 3 terms |
maxItems caps the size of the dataset, not the price — a term is billed the first time it returns a
record. To cap spend, cap searchTerms or set a charge limit on the run.
Other actors in this category quote the same unit — a search term — but hand it back as one dataset item with every panel nested inside. We charge the same unit and give you flat rows instead, so you can filter, join and load them without unpacking anything.
Use cases
- Track demand for a product or brand week by week and feed it into a forecast.
- Find the regions where a campaign should run, at state, metro or city level.
- Mine rising related queries and topics for SEO and content briefs before the term peaks.
- Follow topic entities (
topic_mid) instead of strings, so one concept stays one row across spellings and languages. - Compare up to five competitors on one scale with
isMultiple. - Watch a category (
category+News Search) for emerging stories. - Score demand for a keyword on YouTube or Google Shopping rather than web search.
Notes
- Public Google Trends data only. No personal data, no login, no Google account.
- Google's numbers are a relative index, not absolute search volume — that is Trends, not the actor.
- A run on datacenter proxies is normal; residential is only used when a tier keeps getting 429, and
is charged by the GB on your account. Set
residentialFallback: falseto forbid it.