In 2025, Google introduced an official API interface for Google Trends. But even now, the API is still operating in test mode, and to gain access to it, you need to submit a special application. As a result, there are not many practical options left for scraping: either use third-party service APIs, which are always paid, or build your own custom scraper.
The latter option can be simplified with ready-made libraries such as pytrends (last updated in 2023). However, professional developers can always take their own path and come up with a custom solution.
A typical request for trend data by keyword using the pytrends library looks like this:
# Do not forget to install everything you need first:
# pip install pytrends requests lxml pandas
from pytrends.request import TrendReq
pytrends = TrendReq(
hl='en-US',
tz=360,
timeout=(10,25),
proxies=['https://127.0.0.1:8080',],
retries=2,
backoff_factor=0.1,
requests_args={'verify':False}
) # Example of working through a proxy and ignoring SSL connection errors
kw_list = ["Python", "Pizza", "Spaghetti"] # List of keywords, no more than 5
pytrends.build_payload(
kw_list,
cat=31,
timeframe='today 5-y',
geo='US',
gprop='news',
sleep=60
) # Request parameters: timeframe (last 5 years), category (31 = "Programming"),
# region ("US"), result grouping ("News" only), and delay between requests (60 seconds)
data = pytrends.interest_over_time() # Returns data as a pandas DataFrame
print(data.head()) # Print headers to the console
If this answer is not enough for you, let's go deeper into the details and explain how to build your own Google Trends scraper.
Google Trends is an official free service from Google that allows you to study audience interest in specific keywords and search queries with filters for region, time period, and category. Groups of queries can be compared with each other, or the same queries can be compared against themselves across different locations and time periods.
The only drawback is that Google does not show the exact number of searches, so the statistics are somewhat relative. Instead, the output is given as a percentage-based score — an index from 0 to 100. Sometimes special labels are assigned, such as Breakout, which clearly highlight queries that have gone especially viral.
For understanding the situation, emerging trends, and broader patterns, this data is more than sufficient.
Popular queries related to the main term, as well as queries that are only starting to gain traction, can be downloaded as CSV files. Technically, these are already ready-to-use tabular datasets that can be analyzed further.
However, it is very difficult to process large volumes of data manually, which is why automatic Google Trends scraping becomes necessary. A high-quality Google Trends scraper:
Below, we will look at the most likely ways to scrape Google Trends.
Why is direct DOM scraping a bad idea? The main reason is that Google Trends protects its HTML code and classes by using unique identifiers that are mixed into the final code during rendering in the browser. These are autogenerated Closure classes. The identifiers differ not only from page to page, but also from session to session, which makes it nearly impossible to reliably find repeating elements or extract specific data.
A typical line of code responsible for displaying popular queries in a table may look something like this:
<div jsaction="mouseenter:LAIBnf; mouseleave:vDJIge" class="MzJVtd" jscontroller="OLv9M"><span class="Z9Uqw">THE QUERY ITSELF APPEARS HERE</span></div>
You could try to rely only on HTML tags and their nesting structure, but then even the smallest structural change would break your scraper.
And here is the final complication: you can only get the rendered HTML if you use a real browser. For automation, that means relying on headless browsers or anti-detect browsers.
Requests alone will not save you here.
The most obvious move is this: if Google does not provide open access to the official API, look for existing third-party implementations. Such services do exist. Here are a few examples:
SerpApi — 250 requests per month for free, premium plans starting at $25/month, returns structured JSON.
Apify — a universal cloud scraper with a large number of ready-made scripts, including support for Google Trends scraping. Data can be exported in JSON, CSV, Excel, XML, or HTML. It accepts either search queries or prebuilt filter configurations as input. The base subscription starts at $26/month, plus the cost of request packages (from $0.30 per 1,000 transactions).
ScraperAPI — also a universal scraping platform, with a ready-made Google Trends scraper. Responses can be returned in JSON, as well as in Markdown or plain text for LLM use. Plans start at $44/month and include expiring request packages.
There are many similar cloud scraping services. The logic is fairly simple: they act as intermediaries and do the actual page scraping themselves, while returning only ready-made structured data to you, either in the markup you need or in one of the standard formats such as JSON.
Connection options for such services should be studied in their documentation. In most cases, user authentication is handled through an API key, so that no one else can use your prepaid request package.
We also offer cloud scrapers — Froxy Scrapers — although Google Trends is not currently supported there. As a possible workaround, you could consider using a universal HTML scraper.
Even though the library was last updated in 2023, its principles remain quite workable. The reason is that PyTrends does not parse the DOM structure itself — we already explained above why that approach is unreliable — but instead connects directly to the internal Google Trends API endpoints. These endpoints return clean data without UI components, which are then rendered on the page by Google's own front-end frameworks.
The workflow of PyTrends looks roughly like this:
However, because Google periodically changes its endpoints and actively monitors any automation, you can run into blocks quite quickly:
Related reading: reCAPTCHA and hCaptcha: a guide for scraping.
Possible countermeasures:
See also a guide to successful scraping without blocks.
Perfect proxies for accessing valuable data from 200+ locations around the world.
This scraper:
So, here is the code itself:
# Do not forget to install the required libraries first - pip install pandas pytrends-modern[browser]
import random
import time
from pathlib import Path
import pandas as pd
from pytrends_modern import TrendReq, BrowserConfig
# =========================================================
# CONFIG
# =========================================================
KEYWORDS_FILE = "keywords.txt"
OUTPUT_DIR = Path("output")
OUTPUT_FILE = OUTPUT_DIR / "trends.csv"
HEADLESS = False
LANG = "en-US"
TIMEZONE = 360
MIN_DELAY = 4
MAX_DELAY = 9
RETRIES = 3
# =========================================================
# PROXY
# =========================================================
# pytrends-modern uses common proxy URL
PROXY_SERVER = (
"http://proxy_user:proxy_password@proxy-host:port"
)
# =========================================================
# LOAD KEYWORDS
# =========================================================
def load_keywords():
with open(KEYWORDS_FILE, "r", encoding="utf-8") as f:
return [
line.strip()
for line in f
if line.strip()
]
# =========================================================
# CREATE CLIENT
# =========================================================
def create_client():
os_choice = random.choice([
"windows",
"macos",
"linux"
])
browser_config = BrowserConfig(
# browser
headless=HEADLESS,
# delays
min_delay=MIN_DELAY,
max_delay=MAX_DELAY,
# fingerprint rotation
os=os_choice,
# browser behavior
humanize=True,
# persistent browser profile
persistent_context=True,
# proxy
proxy_server=PROXY_SERVER,
)
pytrends = TrendReq(
hl=LANG,
tz=TIMEZONE,
retries=RETRIES,
browser_config=browser_config,
)
return pytrends
# =========================================================
# FETCH RELATED QUERIES
# =========================================================
def fetch_related_queries(pytrends, keyword):
print(f"[+] Fetching keyword: {keyword}")
try:
pytrends.build_payload(
kw_list=[keyword],
timeframe="today 12-m",
geo=""
)
related = pytrends.related_queries()
keyword_data = related.get(keyword)
if not keyword_data:
return []
rows = []
# top + rising
for trend_type in ["top", "rising"]:
df = keyword_data.get(trend_type)
if df is None:
continue
for _, row in df.iterrows():
rows.append({
"source_keyword": keyword,
"related_keyword": row.get("query"),
"value": row.get("value"),
"trend_type": trend_type,
})
return rows
except Exception as e:
print(f"[!] Error for '{keyword}': {e}")
return []
# =========================================================
# MAIN
# =========================================================
def main():
OUTPUT_DIR.mkdir(exist_ok=True)
keywords = load_keywords()
if not keywords:
print("[!] No keywords found")
return
print("[+] Initializing pytrends-modern...")
pytrends = create_client()
all_rows = []
for keyword in keywords:
rows = fetch_related_queries(
pytrends,
keyword
)
all_rows.extend(rows)
sleep_time = random.uniform(
MIN_DELAY,
MAX_DELAY
)
print(f"[+] Sleep: {sleep_time:.2f}s")
time.sleep(sleep_time)
if not all_rows:
print("[!] No data collected")
return
df = pd.DataFrame(all_rows)
df.to_csv(
OUTPUT_FILE,
index=False,
encoding="utf-8-sig"
)
print(f"[+] Saved: {OUTPUT_FILE}")
print(f"[+] Rows: {len(df)}")
if __name__ == "__main__":
main()
Considering that Google Trends now has an official API for scraping, even if it is still in closed testing, this suggests that Google is not opposed to sharing search trend statistics with its users. In addition, data on popular phrases can be downloaded in CSV format, and some information is visible even without authorization. The only real concern is the added load on Google's infrastructure. That is exactly why the company actively protects itself from automation tools and bots: it shows captchas and blocks access from specific IP addresses.
If you keep your request frequency at a reasonable level and do not create excessive load, everything should be fine. You are not violating any laws or rules, at least as long as your goals are research-related and you are not infringing copyright or intellectual property laws.
The allowed request frequency is not formally defined anywhere. It can only be determined experimentally. At the same time, it is important to remember that Google Trends protection mechanisms may change at any moment. As a result, a request frequency that worked before may suddenly stop working.
At the moment, there is no confirmed public data on safe request volume. If you want to avoid being banned, start with delays of about one minute and then gradually reduce them while looking for a workable middle ground. It is also worth considering that some number of "new" requests may be processed faster, and only after that internal protection kicks in. The PyTrends documentation mentions a limit of 1,400 requests in the first 4 hours, but this may be badly outdated — those figures date back to 2023.
Of course. You can use any programming language. Python simply has ready-made libraries such as PyTrends and PyTrends Modern. But you can study how they work and port the logic to any other language. And if you publish your own libraries afterward, the community will probably be grateful.
Google's protection mechanisms have become more advanced. The first and most important tool is high-quality proxies. On top of that, you can build a realistic browser profile and think about emulating user behavior, including randomized delays between requests. Invisible captcha can work like a WAF (web application firewall) — it analyzes many user parameters and evaluates how "human" the behavior appears.
High-quality proxy servers for web scraping can be purchased from us. Froxy provides millions of residential and mobile proxies with maximum trust and automatic rotation.