Google Trends Scraper: Interest Over Time, Regions & Queries avatar

Google Trends Scraper: Interest Over Time, Regions & Queries

Pricing

Pay per event

Go to Apify Store
Google Trends Scraper: Interest Over Time, Regions & Queries

Google Trends Scraper: Interest Over Time, Regions & Queries

Get Google Trends interest over time, interest by region and top and rising related queries for any term, region and time range, plus daily trending searches. $3 per 1,000 trend rows, $1 per 1,000 trending searches, proxy included; failed queries are free.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Changefeeds Tools

Changefeeds Tools

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Google Trends Scraper: Interest Over Time, Regions & Related Queries

  • What you get: for each search term and region, the data the trends.google.com Explore page shows: interest over time, interest by region, and top and rising related queries. Optionally today's trending searches per country.
  • Built for Google's 429s: residential proxy, cookie handling and up to 8 fresh sessions per blocked query. No Google account, cookie or API key.
  • Price: $3 per 1,000 trend rows and $1 per 1,000 trending searches, proxy included. Blocked, failed and no-data queries are free.

Sample output

The prefilled input (chatgpt, US, past 90 days), run on 2026-10-23, gave one row. Its contents:

Part of the rowWhat came back
timeline93 daily points, 2026-07-23 to 2026-10-23. Last three: Oct 21 = 80, Oct 22 = 79, Oct 23 = 69 (isPartial: true)
regions51 (50 states + DC). Top three: California 100, New Jersey 95, Texas 95
relatedQueries.top25. First three: "chatgpt ai" 100, "chatgpt login" 73, "chatgpt free" 61
relatedQueries.rising7. First three: "sam altman chatgpt water usage" Breakout, "chatgpt astra" +2,250%, "chatgpt student offer" +500%
relatedTopicsempty (Google returned none; see Limits)

The same row as JSON, with each list cut to its first entries:

{
"type": "trend",
"input": "chatgpt",
"terms": ["chatgpt"],
"term": "chatgpt",
"compared": false,
"geo": "US",
"timeRange": "today 3-m",
"resolvedTime": "2026-07-23 2026-10-23",
"resolution": "DAY",
"category": 0,
"property": "",
"timeline": [ // 93 daily points; last 2 shown
{ "time": 1792627200, "date": "2026-10-22T00:00:00.000Z", "formattedTime": "Oct 22, 2026", "value": 79, "values": [79], "isPartial": false },
{ "time": 1792713600, "date": "2026-10-23T00:00:00.000Z", "formattedTime": "Oct 23, 2026", "value": 69, "values": [69], "isPartial": true }
],
"averages": null,
"regions": [ // 51; top 2 shown
{ "geoCode": "US-CA", "geoName": "California", "value": 100, "values": [100] },
{ "geoCode": "US-NJ", "geoName": "New Jersey", "value": 95, "values": [95] }
],
"regionResolution": "REGION",
"relatedQueries": {
"top": [ // 25; first shown
{ "term": "chatgpt", "query": "chatgpt ai", "value": 100, "formattedValue": "100", "link": "https://trends.google.com/trends/explore?q=chatgpt+ai&date=today+3-m&geo=US" }
],
"rising": [ // 7; first shown
{ "term": "chatgpt", "query": "sam altman chatgpt water usage", "value": 7900, "formattedValue": "Breakout", "link": "https://trends.google.com/trends/explore?q=sam+altman+chatgpt+water+usage&date=today+3-m&geo=US" }
]
},
"relatedTopics": { "top": [], "rising": [] },
"exploreUrl": "https://trends.google.com/trends/explore?date=today+3-m&geo=US&q=chatgpt&hl=en-US",
"notes": ["Google returned an empty related-topics list for \"chatgpt\"."],
"noData": false,
"scraped_at": "2026-10-23T03:49:26.658Z"
}

How to run in 30 seconds

  1. Click Try for free. The input already holds chatgpt, region US, past 90 days.
  2. Click Start. Our test run of that input took 16 seconds and returned one trend row: $0.003 at today's price (that run was billed $0.004, the price until 2026-10-23).
  3. Open the Output tab, or export the dataset as JSON, CSV or Excel.

For your own terms, replace chatgpt in Search terms or Trends URLs (or paste a trends.google.com Explore URL), and change Region and Time range. Tick Compare terms together to put up to 5 terms on one 0-100 scale.

Pricing

  • $0.003 per trend row (trend-returned), $3 per 1,000. One row is a term (or a group of up to 5 compared terms) in one region, with its timeline, regions and related queries. Proxy traffic is included.
  • $0.001 per trending row (trending-returned).
  • Free: status rows (blocked, invalid, error), trend rows where Google had no data at all (noData: true), and the run_info row.
  • If you set a maximum total charge, the actor checks the remaining budget before every query, never fetches a row it could not bill, and stops cleanly with "max_total_charge_reached" in OUTPUT.stopped_reason.

Example: tracking 20 keywords every week is 20 rows × about 4.3 runs a month, so about 86 rows, or about $0.26 a month.

FAQ

Do I need a Google account or API key? No.

Is this the official Google Trends API? No. It reads the same public JSON endpoints the trends.google.com page uses.

Why are my numbers different from the website? Check that you use the same region, time range, category and search type (the exploreUrl on each row opens exactly what was queried), and that you compared the same terms together. Google also re-samples, so small differences are normal.

Can I get more than 5 terms on one scale? Google compares at most 5 terms at a time. A common workaround is to put one anchor term in every group and rescale the groups against it. The actor does not do that for you.

Can I compare this week's run with last week's? Not directly: Google rescales every request from 0 to 100. Compare points inside one run's timeline instead. With today 3-m you get daily points, so read the last 7 complete days against the previous 7 and skip the final isPartial point.

How do I track keywords every week? Save the input as a task, add a schedule (for example cron 0 8 * * 1, Mondays 08:00; a new schedule starts disabled, so enable it), and add Google Sheets, Zapier, Make or n8n under the task's Integrations. A plain webhook sends run metadata, not rows; fetch the items from the run's resource.defaultDatasetId (webhook docs).

Limits

  • Google's numbers are relative, not search counts. Every value is scaled 0-100 within its own query. The same term alone and inside a comparison gives different numbers, and so do two different time ranges.
  • Google's own sampling. Re-running a query can shift values by a point or two, and very small terms flicker between some data and none.
  • Related topics usually come back empty. In every live test so far (September and October 2026) Google returned an empty related-topics list to this client, even for big terms. The actor passes on what Google returns and says so in notes. The comparison view has no related topics at all.
  • Rising queries are Google's list, noise included. On 2026-10-03 we saw "how to cook pasta" as a rising query for "ai agents" on the Explore page itself. Keeping only rising queries that contain your term removes most of it, but also drops close variants.
  • Trending searches are Google's RSS feed: about 10 current searches per region, with traffic buckets like "500+" and a few news links. Not the full list on the website, and not historical.
  • Blocking can still win. A query still blocked after 8 new sessions is reported as a free blocked row, not retried forever. Without a proxy (your own IP) the actor only backs off and retries 3 times.
  • It stays polite: one query at a time, at least 0.5 s between requests, 5xx retried with backoff, Retry-After honoured up to 60 s. It never tries to solve Google's CAPTCHA.

Input reference

FieldTypeDefaultWhat it does
searchTermslist of strings—Terms to look up. You can also paste trends.google.com/trends/explore?q=... URLs: a URL is fetched with its own terms, geo, date, cat and gprop, and the terms in one URL are compared together. Topic ids like /m/0dl567 work too.
compareTogetherbooleanfalseOff: each term is queried alone (scaled 0-100 against itself). On: terms are compared in groups of up to 5 (Google's limit), one row per group, scaled against each other.
geostring""Empty = worldwide. A country (US), subregion (US-CA, GB-ENG) or metro (US-CA-807). Comma-separated codes give one row per term per region.
timeRangeselecttoday 12-mnow 1-H, now 4-H, now 1-d, now 7-d, today 1-m, today 3-m, today 12-m, today 5-y, all (2004 to present). A custom YYYY-MM-DD YYYY-MM-DD range is also accepted.
categoryinteger0A Trends category id (the cat= value in a Trends URL). 0 = all categories.
propertyselect"""" web search, images, news, froogle (Google Shopping), youtube.
includeRegionsbooleantrueAdd interest by region. One extra request per row.
includeRelatedbooleantrueAdd top and rising related queries (and related topics for single terms).
trendingNowbooleanfalseAlso output today's trending searches for each region in geo (US when geo is empty). Works with no search terms.
proxyproxyresidential, USLeave on. Turn off only when running from your own network.

Three AI assistants compared in the US over 90 days:

{ "searchTerms": ["chatgpt", "gemini", "claude"], "compareTogether": true, "geo": "US", "timeRange": "today 3-m" }

Output reference

trend rows

  • timeline[].value is the 0-100 interest for a single-term row. In a comparison row it is null: use values, one number per entry in terms, in the same order. A bucket Google marks as having no data is null, not 0. isPartial: true marks the latest, still-incomplete bucket.
  • averages is Google's per-term average for the range. Google returns it only for comparisons; single-term rows have null.
  • regions in a single-term row are 0-100 relative to the top region. In a comparison row they are each term's share of that region's searches among the compared terms, in percent. Regions with no data are left out. regionResolution says whether these are countries, regions (states) or DMA metros.
  • relatedQueries.top values are 0-100 relative. rising values are the percent increase; Google labels increases over 5000 % as "Breakout", kept in formattedValue. Every item carries the term it belongs to.
  • notes says why a field is empty, for example too little search volume.
  • exploreUrl opens the same query on trends.google.com.

When Google has no data at all for a query you still get the row, with empty fields, a note and noData: true. It is not charged.

From a live run (trendingNow: true, geo: "US,GB", 2026-09-30), trimmed:

{
"type": "trending",
"geo": "US",
"title": "evan bouchard",
"approxTraffic": "500+",
"approxTrafficMin": 500,
"pubDate": "2026-09-30T05:00:00.000Z",
"picture": "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcRY6KarQldgLOIhenYpGzGBRIYWIYlvzsuSV99HI_Y-MKGguer3T3D_orYEPAo",
"pictureSource": "NHL.com",
"newsItems": [ // 3; first shown
{
"title": "Bouchard earns second hat trick",
"snippet": null,
"url": "https://www.nhl.com/video/van-edm-bouchard-has-a-hat-trick-against-the-canucks-6405939435112",
"picture": "https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcRY6KarQldgLOIhenYpGzGBRIYWIYlvzsuSV99HI_Y-MKGguer3T3D_orYEPAo",
"source": "NHL.com"
}
],
"exploreUrl": "https://trends.google.com/trends/explore?date=now+1-d&geo=US&q=evan+bouchard&hl=en-US",
"scraped_at": "2026-09-30T05:25:34.633Z"
}

status rows (free)

{ "type": "status", "input": "chatgpt", "mode": "trend", "geo": "US", "status": "blocked", "error": "HTTP 429: Google reported unusual traffic from this IP; still blocked after 8 proxy rotations", "checked_at": "2026-09-30T05:25:18.678Z" }
  • invalid: not a usable term, Trends URL or geo code, or Google rejected the query with HTTP 400 (bad category or time range).
  • blocked: Google kept answering 429 after every retry and rotation.
  • not_found: the trending feed for a region had no items.
  • error: any other HTTP or network failure.

The key-value store record OUTPUT holds a run summary: rows by type, charged counts per event, stopped_reason, truncated_inputs (what was skipped because the budget ran out), HTTP requests, retries and proxy rotations. Every run writes at least one dataset row.

How blocking is handled

  • Google's first-contact 429 (the one that hands out an NID cookie) is recognised as a cookie handshake and retried at once with that cookie.
  • A real block (a 429 "unusual traffic" page, or a redirect to Google's consent or sorry page) makes the actor wait, move to a new proxy session (a new IP) with a new cookie, and try again, up to 8 times with growing backoff.
  • A query still blocked after that becomes a free blocked row and the run moves on; one bad query never fails the whole run.

Troubleshooting: pytrends 429 TooManyRequestsError

If you use pytrends and hit ResponseError: The request failed: Google returned a response with code 429 (TooManyRequestsError), you have met one of the library's longest-running issues. It happens whether you make one request or a thousand.

Why it happens

There is no public Google Trends API. pytrends reverse-engineers the requests the trends.google.com website makes, so every call is an anonymous, cookie-less request against an interface Google did not design for programs. Google rate-limits that pattern by IP, and seemingly by request velocity and shape.

Free fixes

  • Add retries with backoff at construction time:
from pytrends.request import TrendReq
pytrends = TrendReq(
hl='en-US',
tz=360,
retries=2,
backoff_factor=0.5,
)
  • Space out requests and batch fewer keywords per call (Trends compares up to 5 terms at a time).
  • Route through your own rotating residential proxies: TrendReq accepts a proxies parameter.
  • Add jitter and cache aggressively; only re-fetch what is stale.

None of this guarantees success, and Google's backend changes without notice.

What this actor does about it

Residential proxy with per-session cookie handling and rotation, retrying through fresh IPs up to 8 times with backoff. Blocked and no-data queries are not charged.