Google Trends Scraper avatar

Google Trends Scraper

Pricing

Pay per event

Go to Apify Store
Google Trends Scraper

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

Muhammad Ahmed

Maintained by Community

Actor 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 Breakout instead 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

FieldTypeDescription
keywordsarraySearch terms. Scraped separately unless compareKeywords is on
startUrlsarrayGoogle Trends explore URLs — filters are read from the link
compareKeywordsbooleanScrape all terms as one comparison on a shared scale (max 5)
dataTypesarrayinterestOverTime, interestByRegion, relatedQueries, relatedTopics
geostringEmpty for worldwide, or US, GB, US-CA, US-NY-501
timeRangestringnow 7-d, today 12-m, today 5-y, all, or 2024-01-01 2024-06-30
categoryintegerGoogle Trends category id (0 = all, 71 = Food & Drink, 7 = Finance)
propertystringWeb (default), news, images, youtube, froogle (Shopping)
trendingNowGeosarrayAlso return current trending searches for these countries
trendingTimeframeHoursintegerTrending window: 4, 24, 48 or 168 (7 days)
trendingCategoryIdsarrayKeep only these trending category ids
trendingMaxItemsintegerCap trending searches per region (default 500)
trendingIncludeNewsbooleanAttach news articles where Google's RSS feed overlaps
maxItemsintegerStop after this many dataset items (0 = no limit)
concurrencyintegerParallel keyword requests (default 2)
requestDelayMsintegerDelay between requests (default 800)
proxyConfigurationobjectOptional — 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 hasDatafalse 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 compareKeywords to put terms on one scale.
  • The final data point is usually partial. It carries isPartial: true because 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.
  • relatedTopics is 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. trendingIncludeNews is 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 proxyConfiguration so requests rotate across IPs.
  • If you see rate-limit warnings, lower concurrency to 1 and raise requestDelayMs. Slower pacing avoids the retry entirely and is usually faster overall than backing off after a block.

Local development

npm install
npm run build
node dist/main.js # reads storage/key_value_stores/default/INPUT.json