By Ryu Moon
"How do I get Google Trends data in Python?" is one of the most common questions people type once they have outgrown clicking around trends.google.com. You want the interest-over-time line for a list of keywords as a table, you want to compare countries, or you want the rising "Breakout" searches every morning without copying them by hand.
This guide shows how to pull Google Trends data from Python (or JavaScript) with a few lines of code: interest over time, interest by region, related queries, related topics and today's trending searches. It uses Google Trends Scraper – Interest, Regions & Related, an Apify Actor I publish.
Is there an official Google Trends API?
For most people, no. Google does not offer a general public Google Trends API you can sign up for, which is why "does Google Trends have an API" and "is Google Trends API free" are such common searches.
The usual answer used to be pytrends, the unofficial Python library. It is still installable, but its GitHub repository (GeneralMills/pytrends) is now archived and read-only, and its last commit was in August 2024. "pytrends not working" is a common search for a reason: Google Trends replies with HTTP 429 ("Too many requests") very quickly, especially to requests from cloud servers.
If you only need a few keywords now and then, downloading the CSV from the Trends website is fine. A hosted scraper is worth it when you want many keywords, several countries, a schedule, or a pipeline that keeps working without you having to deal with rate limits.
What the Actor returns
You get one row per keyword and data type, so a whole five-year timeline is a single row, not hundreds.
dataType |
What it holds | Key fields |
|---|---|---|
interestOverTime |
The 0–100 timeline | timeline (list of date, formattedTime, value, isPartial), average, comparedWith |
interestByRegion |
Interest per country, region, city or US metro | regions (list of geoCode, geoName, value) |
relatedQueries |
Top and rising searches | top, rising (each item has query, value, formattedValue, isBreakout) |
relatedTopics |
Top and rising topics (entities) | top, rising (each item has title, topicType, value, formattedValue) |
trendingSearch |
Today's "Trending now" list | rank, title, approxTraffic, news |
Every row also carries keyword, geo, timeframe, a trendsUrl you can open to check it against the website, and scrapedAt.
Here is a shortened interest-over-time row from the Actor's README:
{
"dataType": "interestOverTime",
"keyword": "air fryer",
"comparedWith": ["slow cooker"],
"average": 61,
"timeline": [
{ "date": "2021-11-07T00:00:00.000Z", "formattedTime": "Nov 7 – 13, 2021", "value": 74, "isPartial": false }
],
"geo": "GB",
"timeframe": "today 5-y",
"trendsUrl": "https://trends.google.com/trends/explore?q=air+fryer&geo=GB&date=today+5-y"
}
Remember that Google Trends values are relative (0–100 within your chosen keywords, place and time), not absolute search volumes.
Option 1: no code, in Apify Console
- Open apify.com/ryumoon-data/google-trends-scraper-all-in-one and try it in Apify Console (a free Apify account is enough).
- Add your Keywords (up to 100 per run).
- Set Country or region (
GB,US,US-CA… or empty for worldwide) and a Timeframe such astoday 5-y, or a custom range like2025-01-01 2025-12-31. - Turn off the data types you don't need, and switch on Compare keywords against each other if you want the same scale as the website's comparison view.
- Click Start, then export the results as JSON, CSV or Excel.
Option 2: get Google Trends data in Python
Install the official client and put your API token (Apify Console → Settings → API & Integrations) in an environment variable:
pip install apify-client
export APIFY_TOKEN="your-own-token-here"
This script compares two keywords in the UK over five years and saves the weekly timeline as a CSV with one column per keyword:
import csv
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run_input = {
"keywords": ["air fryer", "slow cooker"],
"geo": "GB",
"timeframe": "today 5-y",
"compareKeywords": True, # same 0-100 scale for both, like the website
"interestOverTime": True,
"interestByRegion": False, # turn off what you don't need to save cost
"relatedQueries": True,
"relatedTopics": False,
}
run = client.actor("ryumoon-data/google-trends-scraper-all-in-one").call(run_input=run_input)
items = client.dataset(run["defaultDatasetId"]).list_items().items
# Build one table: date, air fryer, slow cooker
table = {}
for row in items:
if row.get("dataType") != "interestOverTime" or row.get("noData"):
continue
for point in row["timeline"]:
table.setdefault(point["date"][:10], {})[row["keyword"]] = point["value"]
with open("trends.csv", "w", newline="") as f:
writer = csv.writer(f)
writer.writerow(["date"] + run_input["keywords"])
for date in sorted(table):
writer.writerow([date] + [table[date].get(k, "") for k in run_input["keywords"]])
print(f"Saved {len(table)} dates to trends.csv")
Open trends.csv in Excel or Google Sheets, or load it with pandas.read_csv("trends.csv") and plot it.
Find rising and Breakout searches
The same run also returned related queries. This prints the rising ones and marks the Breakout terms (Google's label for growth above 5,000%):
for row in items:
if row.get("dataType") != "relatedQueries" or row.get("noData"):
continue
print(f"\nRising searches for '{row['keyword']}':")
for q in row.get("rising", [])[:10]:
flag = " <- Breakout" if q.get("isBreakout") else ""
print(f" {q['query']} {q['formattedValue']}{flag}")
This is the list that is most useful for content and product ideas, and it's tedious to copy from the website by hand.
Today's trending searches
"Trending now" works without any keywords. Set trendingSearches and list the countries:
run = client.actor("ryumoon-data/google-trends-scraper-all-in-one").call(run_input={
"keywords": [],
"interestOverTime": False,
"interestByRegion": False,
"relatedQueries": False,
"relatedTopics": False,
"trendingSearches": True,
"trendingGeos": ["US", "GB"],
"maxTrendingPerGeo": 10,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
if row.get("dataType") == "trendingSearch":
print(row["geo"], row["rank"], row["title"], row.get("approxTraffic"))
Put this on an Apify schedule and you have a daily trending-searches feed for newsjacking or social posts.
Option 3: JavaScript / Node.js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('ryumoon-data/google-trends-scraper-all-in-one').call({
keywords: ['electric bike', 'e-scooter'],
geo: 'US',
timeframe: 'today 12-m',
interestOverTime: false,
interestByRegion: true,
regionResolution: 'REGION', // US states
relatedQueries: false,
relatedTopics: false,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const row of items) {
if (row.dataType !== 'interestByRegion' || row.noData) continue;
const top5 = row.regions.slice(0, 5).map((r) => `${r.geoName} (${r.value})`);
console.log(`${row.keyword}: ${top5.join(', ')}`);
}
Install the client with npm install apify-client and run it as an ES module (Node 18 or later).
Dealing with Google's rate limits
This is the part that breaks most home-made scripts. The Actor keeps the Trends cookie, waits between requests (minDelayBetweenRequestsSecs, default 1.5 seconds), retries with back-off (maxRetries, default 6) and moves to a new residential IP when it is blocked. Residential proxy is the default. If a request still fails after every retry, it is skipped and listed in the run's SUMMARY, and you are not charged for it.
If you run very large batches and see skipped requests, raise the delay a little before raising the retries.
What it costs
Prices from the live Apify Store listing on 12 Nov 2026 (pay per event):
- Trends result (one keyword × one data type, for example a full timeline): $0.004
- Trending search (one row): $0.001
- Actor start: $0.0001 per GB of memory used by the run
So the Python example above (2 keywords × 2 data types) is 4 results, about $0.016 plus the tiny start fee. Empty answers ("noData": true, common for related topics on niche keywords) are free, and you can cap any run with Apify's "Maximum cost per run" setting. New Apify accounts get a monthly free usage credit, which is enough to try this many times.
Tips and limits
- Values are relative. Compare keywords in the same run with
compareKeywords: true(groups of up to 5) if you want to say "A is searched twice as much as B". - Long timeframes give weekly or monthly points;
now 7-dgives hourly points. - Use
searchPropertyto switch to YouTube, News, Image or Google Shopping search. - For actual long-tail keyword lists rather than trends, the Keyword Autocomplete Actor is a better fit.
Wrapping up
Without an official public Google Trends API and with pytrends archived, a hosted scraper is the least fragile way to get Google Trends data into Python, a spreadsheet or an AI agent. Try Google Trends Scraper with a couple of keywords first, keep only the data types you need, and schedule it once the output looks right.
Comments
Join the discussionNo comments yet. Be the first to comment.