Google Trends Scraper
Pricing
Pay per event
Google Trends Scraper
Scrape Google Trends without the failures. Interest over time, interest by region, rising and breakout queries, keyword comparison, and up to 2,600+ trending searches per region with search volume.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Muhammad Ahmed
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
13 days ago
Last modified
Share
Pull interest over time, interest by region, related and rising queries, related topics, and trending searches from Google Trends — without the failures that plague other Trends scrapers.
Why this one
Google Trends' internal API rejects requests from datacenter IPs with HTTP 429 before it reads anything else. Scrapers that skip the session handshake fail a large share of their runs — the most-used Google Trends Actor on Apify Store currently fails about one run in four.
This Actor performs the handshake Google expects, refreshes the session automatically when a request is throttled, and paces requests instead of bursting. In testing it completed 10 out of 10 keywords from a single datacenter IP with no proxy — and for sustained high-volume runs it supports proxy rotation.
Concretely, it also gives you:
- Rising and breakout queries — the fastest-growing searches around your term, flagged when Google reports
Breakoutinstead of a percentage. This is the data SEO and marketing teams actually act on. - Keyword comparison on a shared 0–100 scale, exactly like the Trends UI (up to 5 terms).
- Every search surface — web, News, Images, YouTube, and Google Shopping.
- Any geography — worldwide, country, sub-region (
US-CA), or metro (US-NY-501). - Trending searches at real depth — up to 2,669 per region for a 7-day window (about 500 for 24h), each with an estimated search volume, growth figure, category and start time. Google's public RSS feed caps out at 10.
- Paste a Google Trends URL and the keywords, region, time range, category and surface are read straight off the link.
Input
| Field | Type | Description |
|---|---|---|
keywords | array | Search terms. Scraped separately unless compareKeywords is on |
startUrls | array | Google Trends explore URLs — filters are read from the link |
compareKeywords | boolean | Scrape all terms as one comparison on a shared scale (max 5) |
dataTypes | array | interestOverTime, interestByRegion, relatedQueries, relatedTopics |
geo | string | Empty for worldwide, or US, GB, US-CA, US-NY-501 |
timeRange | string | now 7-d, today 12-m, today 5-y, all, or 2024-01-01 2024-06-30 |
category | integer | Google Trends category id (0 = all, 71 = Food & Drink, 7 = Finance) |
property | string | Web (default), news, images, youtube, froogle (Shopping) |
trendingNowGeos | array | Also return current trending searches for these countries |
trendingTimeframeHours | integer | Trending window: 4, 24, 48 or 168 (7 days) |
trendingCategoryIds | array | Keep only these trending category ids |
trendingMaxItems | integer | Cap trending searches per region (default 500) |
trendingIncludeNews | boolean | Attach news articles where Google's RSS feed overlaps |
maxItems | integer | Stop after this many dataset items (0 = no limit) |
concurrency | integer | Parallel keyword requests (default 2) |
requestDelayMs | integer | Delay between requests (default 800) |
proxyConfiguration | object | Optional — the Actor works without a proxy |
Example
{"keywords": ["protein powder", "creatine"],"dataTypes": ["interestOverTime", "interestByRegion", "relatedQueries"],"geo": "US","timeRange": "today 12-m","trendingNowGeos": ["US"]}
Output
One item per keyword:
{"keyword": "protein powder","geo": "US","timeRange": "today 12-m","property": "web","averageInterest": 42.62,"peakInterest": { "date": "Apr 12, 2026", "value": 100 },"interestOverTime": [{ "date": "Aug 10, 2025", "timestamp": 1754784000, "value": 33, "values": { "protein powder": 33 }, "isPartial": false }],"interestByRegion": [{ "geoCode": "US-WY", "geoName": "Wyoming", "value": 100, "values": { "protein powder": 100 } }],"topQueries": [{ "query": "whey protein powder", "value": 100, "formattedValue": "100", "isBreakout": false }],"risingQueries": [{ "query": "bloom clear protein powder", "value": 3300, "formattedValue": "+3,300%", "isBreakout": false }],"scrapedAt": "2026-08-16T18:17:57.485Z"}
With trendingNowGeos, trending items are emitted alongside:
{"type": "trendingNow","geo": "US","rank": 1,"query": "rebel creamery","searchVolume": 200000,"growthPercent": 1000,"categoryId": 10,"startedAt": "2026-08-16T00:20:00.000Z","relatedTerms": ["rebel creamery llc", "rebel ice cream", "ice cream"],"news": []}
Each keyword result also carries hasData — false when Google has no interest data for the
term, which it signals with a series of zeros rather than an error. In comparison mode,
relatedByKeyword holds the related queries for every term, not just the first.
Keywords that fail produce an item with keyword and error, so a failure is visible in your results rather than silently missing.
Notes and limits
- Trends values are relative, not absolute. 100 is the peak within your chosen range and region — it is not a search volume. Comparing two separate runs is meaningless; use
compareKeywordsto put terms on one scale. - The final data point is usually partial. It carries
isPartial: truebecause the current period is still accumulating. Average and peak calculations exclude partial points. - Some terms have no related topics or queries. Google simply has no data for low-volume terms; those fields are omitted rather than faked.
relatedTopicsis frequently empty and is not enabled by default. Google returns HTTP 200 with an empty list for many terms, because topics require the keyword to map to a Knowledge Graph entity — a broad phrase like "protein powder" often has none, while a named entity is more likely to. Enable it if you need it, but do not assume every keyword will populate it.- Comparison is capped at 5 keywords by Google, not by this Actor.
- Trending category ids are numeric. Google does not publish the mapping, so each result carries its own
categoryId— run once without a filter, see which ids matter for your niche, then filter on them. Ids observed in practice include 3, 4, 6, 9, 10, 11, 14, 15, 17, 18 and 20. - News articles come from a different Google feed than the trending list, so only a few results will ever match.
trendingIncludeNewsis off by default to avoid the wasted request. - Rate limits are real at sustained volume. A single IP running normal workloads is fine — 10 keywords in 34 seconds tested clean. Hammering Trends continuously for many minutes will eventually throttle that IP, and recovery takes several minutes. The Actor retries and re-establishes its session automatically, but for large or back-to-back runs enable
proxyConfigurationso requests rotate across IPs. - If you see rate-limit warnings, lower
concurrencyto 1 and raiserequestDelayMs. Slower pacing avoids the retry entirely and is usually faster overall than backing off after a block.
Local development
npm installnpm run buildnode dist/main.js # reads storage/key_value_stores/default/INPUT.json