Google Trends Scraper (Reliable, No Browser)
Pricing
from $2.00 / 1,000 results
Google Trends Scraper (Reliable, No Browser)
Fast, retry-hardened Google Trends scraper. Interest over time, related queries, related topics, interest by region. No browser = lower cost and fewer failures.
Pricing
from $2.00 / 1,000 results
Rating
0.0
(0)
Developer
Steady API
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
9 hours ago
Last modified
Categories
Share
Google Trends Scraper — Reliable, No Browser
Get Google Trends data that actually comes back. No headless browser, no silent empty runs.
Pull interest over time, related queries, related topics and interest by region for any keyword, country and time range.
Why this Actor exists
Google Trends has no official API, so most scrapers either drive a headless browser (slow and expensive) or call the internal endpoints without handling how Google gates them. Both break often.
Here is the thing that most implementations miss:
The Google Trends internal API returns
429 Too Many Requestson the very first call if you do not carry anNIDcookie. It is not a rate limit. It is a gate.
Measured on 2026-09-15:
| Request | Result |
|---|---|
/trends/api/explore with no cookie | 429 |
Same call after one visit to trends.google.com to pick up NID | 200 |
This Actor treats "proxy IP + the cookie issued to that IP" as a single session. When a session gets gated, it throws away the whole session and builds a new one. Refreshing only the cookie does not help, because the IP is already flagged.
What you get
- No browser. Direct JSON endpoints only. Runs finish in seconds and cost a fraction of a browser-based Actor.
- Retry that understands the failure. Exponential backoff with jitter on
429and5xx. Empty200bodies are treated as a silent throttle and retried, not returned as success. - Partial success by default. One bad keyword does not kill the run. Failed keywords come back as rows with an
errorand anerrorTypeso you know exactly what is missing and why. - A run summary you can assert on.
RUN_SUMMARYin the key-value store gives yourequested,succeeded,failed,successRateandproxySessionsUsed. - You are not charged for failed keywords.
Input
| Field | Type | Default | Notes |
|---|---|---|---|
keywords | array | required | One or more search terms |
compareKeywords | boolean | false | On: one comparison chart, max 5 keywords, values relative to each other. Off: each keyword on its own 0-100 scale |
timeframe | string | today 12-m | now 1-H … today 5-y, all |
geo | string | "" (worldwide) | US, GB, DE, JP, or sub-regions like US-CA |
includeInterestOverTime | boolean | true | The main trend line |
includeRelatedQueries | boolean | false | Top and rising queries |
includeRelatedTopics | boolean | false | Top and rising topics |
includeInterestByRegion | boolean | false | Country or sub-region breakdown |
category | integer | 0 | Google Trends category ID |
property | string | "" | "" web, images, news, youtube, froogle |
hl / tz | string / int | en-US / 0 | Response language and timezone offset in minutes (0 = UTC) |
requestDelayMs | integer | 1200 | Raise for very large keyword lists |
proxyConfiguration | object | Datacenter | Switch to Residential for thousands of keywords |
Example
{"keywords": ["bitcoin", "ethereum", "solana"],"geo": "US","timeframe": "today 3-m","includeInterestOverTime": true,"includeRelatedQueries": true}
Output
One dataset row per keyword (or per comparison group).
{"keywords": ["bitcoin"],"geo": "US","timeframe": "today 3-m","category": 0,"property": "web","scrapedAt": "2026-09-15T13:02:11.482Z","interestOverTime": [{ "date": "Jun 15, 2026", "timestamp": 1781481600000, "values": [89], "isPartial": false },{ "date": "Sep 15, 2026", "timestamp": 1789430400000, "values": [44], "isPartial": true }],"relatedQueries": {"top": [{ "query": "bitcoin price", "value": 100, "formattedValue": "100" }],"rising": [{ "query": "british man recovers lost bitcoin", "formattedValue": "Breakout" }]}}
isPartial: true marks the current, still-incomplete bucket. Drop those points before charting if you need clean series.
A failed keyword looks like this instead:
{"keywords": ["some-term"],"error": "429 Too Many Requests — temporarily gated by Google","errorType": "BLOCKED_OR_UNAVAILABLE","scrapedAt": "2026-09-15T13:02:14.113Z"}
errorType is either INVALID_REQUEST (your input will never work, fix it) or BLOCKED_OR_UNAVAILABLE (retry later or use Residential proxy).
Notes on the data
Google Trends values are relative, not absolute search volume. 100 is the peak of the selected range, everything else is scaled to that. Two separate runs are not directly comparable unless you use compareKeywords.
Tips
- Scraping thousands of keywords: set
proxyConfigurationto Residential andrequestDelayMsto3000. - Comparing brands: turn on
compareKeywordsso the numbers share one scale. - Building a dashboard: use
timestamp(epoch ms), notdate, which is a localized display string.
Legal
Only public Google Trends data is requested. No login, no personal data, no private endpoints.