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.
What Is Google Trends Data and Why Scrape It
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:
- makes it possible to scale analytics collection for a wide range of tasks — marketing, SEO, competitor analysis, market research, and more;
- helps identify keyword opportunities for creating relevant content such as videos, music tracks, articles, and other materials;
- allows you to study audience response and reactions to major events at scale.
Below, we will look at the most likely ways to scrape Google Trends.
Method 0. Do Not Even Try: DOM Structure Analysis

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.
Method 1. Use a Google Trends Scraper API

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.
Method 2. Scraping Google Trends with PyTrends or Its Forks

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:
- connect to the Google Trends service;
- obtain a token or widget config through /api/explore — this is the main endpoint used for working with data;
- use that token to request the actual data;
- receive the raw data in JSON format;
- convert it into the required format if needed.
However, because Google periodically changes its endpoints and actively monitors any automation, you can run into blocks quite quickly:
- Google may show a captcha, since Google Trends works together with invisible reCAPTCHA v3;
- the server may return a 429 Too Many Requests error;
- or the endpoint may return an empty response altogether.
Related reading: reCAPTCHA and hCaptcha: a guide for scraping.
Possible countermeasures:
- Use high-quality residential or mobile proxies. No VPS proxies, datacenter proxies, or free proxies. The proxies should be as trustworthy as possible.
- Watch your request rate carefully, the lower, the better. Based on feedback from developers who build Google Trends scrapers, this usually means making only a small number of rapid requests at the beginning, and then introducing delays of around one minute once the internal limit is reached. By the way, PyTrends already includes built-in protection: delays increase exponentially when errors occur, according to the formula {backoff factor} * (2 ^ ({number of total retries} - 1)).
- Look for more modern forks of PyTrends where token extraction logic, endpoint addresses, and response parsing have been updated. For example, pytrends-modern is actively maintained, supports working through Selenium and Camoufox with account authorization, asynchronous requests, and manual cookie configuration.
- Better yet, combine PyTrends with a headless browser and high-quality scraping proxies. The browser can handle token retrieval and "human verification" checks, including invisible captcha and a realistic browser fingerprint; proxies can handle IP-based rate limits and blocks; and PyTrends can focus on retrieving structured trend and query data.
See also a guide to successful scraping without blocks.
Residential Proxies
Perfect proxies for accessing valuable data from 200+ locations around the world.
Example of a Google Trends Scraper in Python
This scraper:
- reads a list of search phrases from keywords.txt. It is a simple list where each new phrase is placed on a new line;
- then creates a browser session through pytrends-modern by launching headless Chromium or Camoufox, which connects to an authenticated proxy. This is where you can plug in Froxy proxies. They are connected once, while the rotation logic is configured in the dashboard;
- creates a browser profile, which is effectively a digital fingerprint;
- enables "human-like" behavior that reduces the probability of blocks and captcha prompts;
- launches the browser with support for cookies and local storage. This is where the token is stored, and without it the endpoints cannot be accessed;
- after initialization, the browser opens Google Trends and obtains a working user session;
- then pytrends-modern uses not ordinary HTTP requests, but a browser-backed session. In other words, requests to /trends/api/explore and /trends/api/widgetdata/* are executed as if they were being sent by a real Chromium browser;
- for each search phrase, a payload is built and sent to Google Trends;
- the following data is extracted from the endpoints: top queries, rising queries, and related search phrases;
- random delays are added between requests;
- all results are converted into a unified structure and combined into a single DataFrame, which is then saved as a CSV file.
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()
Frequently Asked Questions

Is it legal to scrape Google Trends?
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.
How often can I update the data?
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.
Can I scrape Google Trends without Python?
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.
What's the best way to avoid getting blocked?
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.

