Google Trends Scraper
Pricing
Pay per usage
Google Trends Scraper
Reliable Google Trends data: interest over time, interest by region, related queries/topics and daily trending searches, with automatic retries, session/proxy rotation and honest error reporting instead of silent failures.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
Relay Data Tools
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 hours ago
Last modified
Categories
Share
Google Trends data - interest over time, interest by region, related queries/topics, and today's trending searches - pulled directly from the same internal endpoints trends.google.com's own web app uses, with the reliability engineering that endpoint actually needs: automatic retries with backoff, session/identity rotation, Apify Proxy support, and honest error reporting instead of silent failures or a crashed run.
Who it's for
- SEO and content teams researching rising queries and regional demand before writing or
prioritizing content, and content planners mapping out a publishing calendar around a
topic's seasonality (e.g. "when does interest in
tax softwarestart climbing each year"). - Market/competitive researchers comparing interest in brands, products, or topics over time and across countries.
- Anyone automating a "what's trending" feed for a newsletter, dashboard, or social media queue.
- Anyone who has been burned by a Trends actor that silently returns nothing, or fails, on a chunk of their runs - see "Why this Actor exists" below.
Why this Actor exists
Google Trends has no public API. Every Trends actor on the market, including this one,
works by replaying the same undocumented trends.google.com/trends/api/* calls the
website itself makes, and Google throttles that traffic aggressively and inconsistently.
The result, in practice, is that most Trends actors fail on a meaningful fraction of runs.
This Actor treats that as the actual product problem to solve: every request goes through
retry + exponential backoff + a full identity rotation (new User-Agent, new cookies, and -
if you attach Apify Proxy - a new IP) rather than failing the run on the first 429, and
every piece of data that couldn't be fetched is reported as an explicit error item instead
of being dropped silently.
Input
{"searchTerms": ["apify", "web scraping"],"geo": "","timeframe": "today 12-m","category": 0,"property": "","includeInterestOverTime": true,"includeInterestByRegion": true,"regionResolution": "COUNTRY","includeRelatedQueries": true,"includeRelatedTopics": false,"trendingNow": false,"trendingNowGeo": "US","proxyConfiguration": { "useApifyProxy": true },"maxRetries": 5,"requestDelayMs": 1000}
| Field | Type | Default | Description |
|---|---|---|---|
searchTerms | array of strings | [] | Up to 5 compared directly per request (Google's own limit). More than 5 are auto-batched - see "Comparing more than 5 terms" below. Can be empty if trendingNow is enabled. |
anchorTerm | string | first term | Only relevant with >5 searchTerms: the term repeated in every batch to keep values comparable across batches. |
geo | string | "" (worldwide) | Two-letter country code ("US"), a region code ("US-CA"), or empty. |
timeframe | string | "today 12-m" | One of the presets (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) or "custom". |
customTimeframeStart / customTimeframeEnd | string (YYYY-MM-DD) | - | Required when timeframe is "custom". |
category | integer | 0 | Google Trends category ID (0 = all categories). |
property | string | "" (web) | "", "news", "images", "youtube", or "froogle" (Google Shopping). |
includeInterestOverTime | boolean | true | Emit interest_over_time rows. |
includeInterestByRegion | boolean | true | Emit interest_by_region rows. |
regionResolution | string | "COUNTRY" | COUNTRY, REGION, CITY, or DMA (US media markets only). |
includeRelatedQueries | boolean | true | Emit related_query rows. |
includeRelatedTopics | boolean | false | Emit related_topic rows. Off by default - see Limitations. |
trendingNow | boolean | false | Emit today's trending searches for trendingNowGeo, independent of searchTerms. |
trendingNowGeo | string | "US" | Country code for the trending-now feed. |
proxyConfiguration | object | Apify Proxy off | Strongly recommended for anything beyond a handful of terms. |
maxRetries | integer | 5 | Retries per request before that piece of data is recorded as an error. |
requestDelayMs | integer | 1000 | Politeness delay (+/-25% jitter) before each request. |
Comparing more than 5 terms
Google Trends compares at most 5 terms per request, and always re-normalizes so the single
highest point across the batch equals 100. To support more terms, this Actor splits them
into batches of <=5 that all repeat one anchor term, then rescales every other batch
onto the first batch's scale using the ratio between the anchor's values in each batch
(median ratio over overlapping points, to smooth out rounding). Rescaled rows carry a
rescaleFactor field so you can see exactly what was applied and audit it. This is
documented here rather than presented as an exact re-derivation of Google's own
normalization - treat cross-batch comparisons as a close approximation, not an exact score.
Output
One dataset row per data point, tagged with a type field so different kinds of rows share
one dataset:
type | One row per | Key fields |
|---|---|---|
interest_over_time | (term, date) | term, date, value (0-100 or null), isPartial |
interest_by_region | (term, location) | term, geoCode, geoName, value, resolution |
related_query | (term, rank) | term, rankType (top/rising), rank, query, value, formattedValue, isBreakout |
related_topic | (term, rank) | same as related_query plus topicTitle, topicType, topicMid |
trending_now | trending item | rank, title, approxTraffic, pubDate, newsItems |
batch_summary | failed request | terms/term, output, error |
validation_error | bad input field | message |
run_summary | once per run | counts, resolved geo/timeframe, requestsMade |
value: null means Google reported no data for that specific point/term - never confused
with a real 0. A noData: true row (with a note) is emitted instead of nothing when an
enabled output returned zero results for a term, so an empty result is always visible and
explained rather than looking like the Actor just skipped that term.
A ready-to-use Overview table view is available in the dataset UI/API.
Limitations
- Google's
RELATED_TOPICSwidget returned no data in testing, even for popular terms. During this Actor's development (2026-09-28),RELATED_QUERIESreliably returned rich data whileRELATED_TOPICScame back as an empty list for every term tested, including a generic, high-volume term ("python", worldwide) that has obvious related topics on the live trends.google.com site. This looks like a gap in the current redesign of Google's Trends API rather than anything this Actor is doing wrong.includeRelatedTopicsis therefore off by default; when enabled, a term that gets nothing back produces an explicitrelated_topicrow withnoData: trueand anote, not silence. If Google fixes this server-side, the same code path will pick up real data automatically. - Related topics always costs one extra request pair per term. Google's API only
returns the
RELATED_TOPICSwidget for a single-term explore call, never for a >1-term comparison batch. So wheneverincludeRelatedTopicsis on, this Actor issues one dedicated single-termexplore+ widget call per term, on top of whatever batch that term was already part of for the other outputs. - Cross-batch rescaling (>5 terms) is an approximation, not an exact re-derivation of Google's normalization - see "Comparing more than 5 terms" above.
- The older
dailytrends/realtime-trends JSON endpoints are gone. They returned404in testing;trendingNowuses thetrending/rssfeed, which was live and working. - No official rate limit is documented. This Actor's retry/backoff/rotation defaults are
a reasonable starting point, not a guarantee - very large or very fast runs should attach
Apify Proxy (
proxyConfiguration) and consider raisingrequestDelayMs. - A snapshot, not a scan. Trends data (especially
related_query/related_topicrankings andtrending_now) changes hour to hour; treat results as "as of this run." - 0-100 is relative, not absolute. Every Trends value is normalized to the peak within the requested batch/timeframe/geo - it is a share-of-search-interest metric, never a raw search-volume count.
FAQ
Why did I get a batch_summary item instead of my data?
Something about that specific request failed after all retries (network error, Google
returned an unexpected shape, or the relevant widget just wasn't in the explore response).
The error field says what happened and for which term/output; everything else in the run
still completed normally.
Why is includeRelatedTopics off by default?
See Limitations - Google's own related-topics widget was unreliable in testing. Turn it on
if your use case can tolerate noData rows; related_query is unaffected and on by
default.
Can I run this without a proxy? Yes, for light usage (a handful of terms, default delay). Google Trends' throttling is IP-based, so any request volume beyond casual use should attach Apify Proxy.
Why are my interest_over_time values floats instead of clean integers?
Only when you compared more than 5 terms - those rows went through the anchor-term
rescaling described above and carry a rescaleFactor. Rows from a single-batch run (<=5
terms) are always the exact integers Google returned.
How is this priced? See PRICING.md for the proposed pay-per-event plan.