Google Trends Scraper — Bulk Keyword Compare avatar

Google Trends Scraper — Bulk Keyword Compare

Pricing

from $1.60 / 1,000 trend results

Go to Apify Store
Google Trends Scraper — Bulk Keyword Compare

Google Trends Scraper — Bulk Keyword Compare

Compare up to 200 Google Trends keywords on one scale, with trend analysis: rising or falling, peak month, share of search. Regions and related queries.

Pricing

from $1.60 / 1,000 trend results

Rating

0.0

(0)

Developer

khalil ben ali

khalil ben ali

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

13 days ago

Last modified

Categories

Share

Google Trends Scraper is an unofficial Google Trends API on Apify, not affiliated with Google. It returns Google Trends data as flat, export-ready JSON: interest over time with built-in trend analysis, interest by region, related queries and the current trending searches. It calls the same JSON endpoints the Google Trends website uses, so there is no browser to maintain and runs finish in minutes.

Google's own site compares at most five keywords at a time and rescales every comparison to its own peak. This Actor lets you compare keywords in bulk: up to 200 keywords land on one common 0-100 scale in a single run.

Key features:

  • Bulk compare: up to 200 keywords on one common scale, or each keyword on its own scale.
  • Trend analysis built in: every interest-over-time result with enough data comes with its trend direction, change in percent and peak. With a year or more of data it also has a peak month, and with two years a year-over-year change and a seasonality index. A Compare all run adds each keyword's share of search and rank within the comparison. It is part of the same result and costs nothing extra.
  • Interest by region: countries, states, cities or US metro areas (DMA).
  • Related queries: the top and the rising queries for every keyword, with breakout flags.
  • Trending now: ranked trending searches for a country, with start time, search volume and growth.
  • HTTP-only reliability: no browser. Sessions pace their requests, replace blocked sessions and stop cleanly when Google keeps blocking.
  • Pay only for successful results: results with status noData, blocked or error are free.

Every result is one dataset item per keyword and data type (or one per trending search).

Record typeWhat it containsKey fields
interestOverTimeSearch interest of a keyword over the chosen period, with trend analysispoints (time, value 0-100, isPartial), averageValue, resolution, scale, and the analysis: trendDirection, changePercent, peakMonth, shareOfSearchPercent, compareRank
interestByRegionWhere a keyword is most searchedregions (geoCode, geoName, value 0-100), resolution
relatedQueriesQueries searched together with the keywordtop (query, value), rising (query, value, formattedValue, isBreakout)
trendingNowWhat people in a country are searching for right nowrank, term, startedAt, endedAt, searchVolume, growthPercent, relatedTerms

Every item also carries keyword, geo, timeRange, category, searchProperty, status, errorMessage and scrapedAt.

Trend analysis: answers, not just numbers

Every interest-over-time item carries analysis fields next to the time series, so you can see whether a keyword is rising, when it peaks and who wins a comparison without post-processing. Each field is filled when there is enough data for it and is null otherwise (the rules are below). They are flat fields, so CSV and Excel exports stay usable. They are part of the same result: no extra charge, no extra input.

All fields are computed from the values you receive in points (after common-scale normalisation and rounding), and only from complete points, the ones with isPartial false. The running period is left out because its value can still change. Below, n is the number of complete points. When status is not ok, every analysis field is null.

FieldThe question it answersExact definition
peakValue, peakTimeHow high did interest go, and when?The highest value among the complete points, and the start time (ISO 8601) of its first occurrence. null when every complete point is 0, because then there is no peak.
recentAverageWhere is interest now?Average of the last quarter of the complete points: the last floor(n / 4) points, rounded to 2 decimals. null with fewer than 8 complete points.
changePercentHow much did interest change?(recent average − first-quarter average) ÷ first-quarter average × 100, rounded to 1 decimal. The first quarter is the first floor(n / 4) complete points. null with fewer than 8 complete points or when the first-quarter average is 0.
trendDirectionIs it rising, falling or flat?rising if changePercent is above +15, falling if it is below −15, otherwise stable (exactly +15 and −15 are stable). If the first-quarter average is 0: rising when recentAverage is above 0, otherwise stable. null with fewer than 8 complete points.
yearOverYearChangePercentIs it higher than a year ago?Average of the complete points in the last 52 weeks (364 days) against the average of the 52 weeks before, counted back from the last complete point: recent ÷ earlier × 100 − 100, rounded to 1 decimal. Weekly data puts 52 points in each window, monthly data 12. Needs complete points that span at least two years (728 days), so use today 5-y or all. null otherwise, or when the earlier average is 0.
peakMonthIn which month is interest highest?The English month name (January to December) whose complete points have the highest average value, grouped by UTC calendar month. Needs the complete points to cover at least 12 distinct calendar months (every month from January to December, in any year, so the default 12 months of weekly data are enough) and resolution DAY, WEEK or MONTH, otherwise null. A tie goes to the earliest month of the year. null as well when every month has the same average (a flat series, for example a keyword stuck at 1, or all zeros), because then no month is the peak.
seasonalityIndexHow seasonal is it?(highest monthly average − lowest monthly average) ÷ overall average, rounded to 2 decimals. 0 = flat all year; higher = stronger seasonal swing. Needs a span of at least two years (728 days) and resolution DAY, WEEK or MONTH. null otherwise, or when the overall average is 0.
shareOfSearchPercentWho has the biggest share?The keyword's sum of complete-point values ÷ the sum over all successful keywords of the comparison × 100, rounded to 1 decimal. The shares of a comparison add up to about 100. Only with Compare all (scale is common), otherwise null. Also null when the comparison did not finish, when any keyword of it ended blocked or error, or when the total is 0 (see Good to know).
compareRankWho is number one?1 = the biggest shareOfSearchPercent (the highest sum of complete-point values) among the successful keywords of the comparison, so the ranks always follow the shares. Keywords with exactly the same sum share a rank (1, 1, 3). Only with Compare all, otherwise null, and null in the same cases as shareOfSearchPercent. It is not the Trending now rank.

Good to know:

  • Only keywords with status ok take part in shares and ranks, and keywords that return noData, blocked or error have null for both. A keyword with noData is simply left out of the comparison. But if any keyword of the comparison ends blocked or error, shareOfSearchPercent and compareRank are null for every keyword of that comparison: shares re-based over the survivors would look like a complete ranking when it is not. The trend analysis of each successful keyword is still filled. Run the comparison again later to get shares and ranks.
  • Share and rank are computed once every keyword of the comparison is finished. A run that was migrated and resumed returns the same numbers as an uninterrupted run. If you stop a Compare all run early, shareOfSearchPercent and compareRank stay null, because the comparison is incomplete. If instead your maximum cost per run stops the saving of results, the shares still refer to the full comparison, so the saved ones add up to less than 100.
  • The default time range (12 months of weekly data) covers every calendar month, so it has a peakMonth. It spans only about 51 weeks, which is too short for yearOverYearChangePercent and seasonalityIndex, which need two years. Use today 5-y or all for those.

Example: which drink is rising, and who wins?

Compare five drinks on one scale over five years in the United States:

{
"keywords": ["coffee", "tea", "matcha", "espresso", "cold brew"],
"compareMode": "compareAll",
"dataTypes": ["interestOverTime"],
"geo": "US",
"timeRange": "today 5-y"
}

Real data from a run on 10 October 2026, analysed with this version: the item for matcha, with points trimmed to two of the 261 weekly points. Google Trends values move over time, so a new run shows slightly different numbers.

{
"recordType": "interestOverTime",
"keyword": "matcha",
"geo": "US",
"timeRange": "today 5-y",
"category": 0,
"searchProperty": "web",
"status": "ok",
"errorMessage": null,
"scale": "common",
"scrapedAt": "2026-10-10T14:13:10.395Z",
"resolution": "WEEK",
"points": [
{
"time": "2021-10-10T00:00:00.000Z",
"timestamp": 1633824000,
"formattedTime": "Oct 10 – 16, 2021",
"value": 1,
"isPartial": false
},
{
"time": "2021-10-17T00:00:00.000Z",
"timestamp": 1634428800,
"formattedTime": "Oct 17 – 23, 2021",
"value": 1,
"isPartial": false
}
],
"averageValue": 3.58,
"peakValue": 8,
"peakTime": "2026-04-05T00:00:00.000Z",
"recentAverage": 6.14,
"changePercent": 238.1,
"trendDirection": "rising",
"yearOverYearChangePercent": 24.4,
"peakMonth": "June",
"seasonalityIndex": 0.51,
"shareOfSearchPercent": 3.5,
"compareRank": 4
}

The results of the whole run, side by side:

keywordaverageValuetrendDirectionchangePercentyearOverYearChangePercentshareOfSearchPercentcompareRankpeakMonthseasonalityIndex
coffee58.58rising50.430.157.41May0.14
tea32.13rising20.912.131.52December0.14
espresso6.23rising99.336.66.13December0.45
matcha3.58rising238.124.43.54June0.51
cold brew1.47rising50.649.31.45June0.80

How to read it: coffee leads with 57.4% of the search interest of the five drinks, and tea follows with 31.5%. Matcha has only a 3.5% share, but it grew the most: its average over the last quarter of the five years is 238% above the first quarter. Cold brew is the most seasonal (index 0.80, peaking in June), while coffee and tea are steady all year (0.14). The shares add up to about 100 (rounding), and the ranks follow the shares. Over long ranges Google sometimes changes how it collects data, which it marks on its own charts, so compare keywords with each other rather than reading a single change in isolation.

  1. Open the Actor in Apify Console and go to the Input tab.
  2. Add your keywords, one per line. Terms and Google topic IDs (for example /m/0dl5d) both work.
  3. Under What to collect, choose interest over time, interest by region and/or related queries. Set Compare mode to compare all keywords on one scale.
  4. Under Location, time and filters, pick a region, a time range, a category and a search property (web, YouTube, news, images or Google Shopping).
  5. Click Start. When the run finishes, open the Output tab to view the results or export them as JSON, CSV or Excel.

To list trending searches instead, set Mode to Trending now.

The Actor uses pay-per-event pricing. At current prices:

  • Run start: $0.003 per run. Apify charges the run start once per GB of memory, minimum one; the default 256 MB counts as one, and the Actor never needs more.
  • Trend result: $0.002 for every successful keyword and data type result.
  • Trending search: $0.0005 for every trending search saved.

Prices are lower on higher Apify plans. They may change, and the Pricing tab of this page is always the authoritative source.

Worked examples (plus the $0.003 run start):

RunBillable resultsApproximate cost
100 keywords, interest over time100$0.20
50 keywords, all three data types (150 results)150$0.30
Trending now, top 100 searches100$0.05

Results with status noData, blocked or error are saved with an explanation and are never charged. If you set a maximum cost per run, the Actor stops cleanly when it is reached and keeps what it saved.

Input

The input form has five groups. Everything has a default, so you can start a run without changing anything: the default compares coffee and tea worldwide over the last 12 months.

  • Keywords: mode (keywords or trendingNow) and keywords, up to 200 per run. Duplicates and empty lines are ignored.
  • What to collect: dataTypes, regionResolution (COUNTRY for worldwide, REGION, CITY or DMA for a country), compareMode (separate or compareAll) and anchorKeyword.
  • Location, time and filters: geo (US, FR, US-CA, or empty for worldwide), timeRange (past hour to 5 years, all or custom), customTimeRange (2025-01-01 2025-06-30), category (0 = all, 20 = Sports, 174 = Science) and searchProperty.
  • Trending now: trendingGeo, trendingHours ("4", "24", "48" or "168") and trendingMaxItems.
  • Advanced: language, timezoneOffsetMinutes and maxConcurrency (1 to 5 parallel sessions, default 2).

If Google rejects a region detail for a country, the Actor uses Google's default breakdown and logs a warning.

{
"mode": "keywords",
"keywords": ["coffee", "tea"],
"dataTypes": ["interestOverTime", "interestByRegion", "relatedQueries"],
"compareMode": "separate",
"geo": "US",
"timeRange": "today 12-m"
}

Example: compare seven keywords on one scale

{
"keywords": ["coffee", "tea", "espresso", "latte", "cappuccino", "matcha", "cold brew"],
"compareMode": "compareAll",
"anchorKeyword": "coffee",
"dataTypes": ["interestOverTime"]
}
{ "mode": "trendingNow", "trendingGeo": "US", "trendingHours": "24", "trendingMaxItems": 100 }

Output

Results are available in the dataset as JSON, CSV, Excel, XML and more. The dataset has views for an overview, interest over time, interest by region, related queries and trending searches. Example interest-over-time item for one keyword on its own scale over 12 months (values are illustrative):

{
"recordType": "interestOverTime",
"keyword": "coffee",
"geo": "US",
"timeRange": "today 12-m",
"category": 0,
"searchProperty": "web",
"status": "ok",
"errorMessage": null,
"scale": "perKeyword",
"scrapedAt": "2026-10-10T12:00:00.000Z",
"resolution": "WEEK",
"points": [
{
"time": "2025-10-05T00:00:00.000Z",
"timestamp": 1759622400,
"formattedTime": "Oct 5 – 11, 2025",
"value": 78,
"isPartial": false
}
],
"averageValue": 81.4,
"peakValue": 100,
"peakTime": "2025-12-14T00:00:00.000Z",
"recentAverage": 86.1,
"changePercent": 7.4,
"trendDirection": "stable",
"yearOverYearChangePercent": null,
"peakMonth": "December",
"seasonalityIndex": null,
"shareOfSearchPercent": null,
"compareRank": null
}

In this example yearOverYearChangePercent and seasonalityIndex are null because 12 months of data are too short for them (they need two years), and shareOfSearchPercent and compareRank are null because the keyword is not part of a Compare all comparison. See the trend analysis section above for every field.

FieldMeaning
statusok, noData (too little search volume), blocked (Google blocked the run, not scraped) or error. Only ok is charged.
errorMessageExplains any status other than ok; null otherwise.
scaleperKeyword: values are relative to the keyword's own peak. common: one scale shared by all keywords of the run.
value (points, regions, top)Google's relative index from 0 to 100, never an absolute search count. Decimals appear when more than five keywords are normalised across batches.
isPartialThe period is not finished yet, so its value can still change.
analysis fieldspeakValue to compareRank, interest over time only. null means there is not enough data, no peak, or no finished comparison, never zero. The trend analysis section has the exact definitions and the null rules.
rising.valueGrowth in percent. isBreakout is true when the growth exceeds 5000%.
searchVolumeTrending now only: Google's rounded approximate number of searches.
endedAt, isActiveTrending now only: endedAt is null and isActive is true while the search is still trending.

Region and related-query values are always relative to the keyword's own peak (scale is perKeyword), even in Compare all mode.

Every Actor run is available through the Apify API. Replace <YOUR_APIFY_TOKEN> with your own API token.

JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('Khalilbenali/google-trends-scraper').call({
keywords: ['coffee', 'tea'],
dataTypes: ['interestOverTime'],
geo: 'US',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

Python

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("Khalilbenali/google-trends-scraper").call(
run_input={"keywords": ["coffee", "tea"], "dataTypes": ["interestOverTime"], "geo": "US"}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
print(item)

cURL

curl -X POST "https://api.apify.com/v2/acts/Khalilbenali~google-trends-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"keywords": ["coffee", "tea"], "dataTypes": ["interestOverTime"], "geo": "US"}'

The synchronous endpoint returns the dataset items directly and suits short runs. For larger runs start the Actor asynchronously and read the dataset when it finishes.

Integrations

Connect the Actor to Make, Zapier, n8n or Google Sheets, or call a webhook when a run finishes, using the Apify integrations. AI agents can run it through the Apify MCP server: the flat output and the status field are easy for a model to read.

Use cases

  • SEO and keyword research: compare keywords on one scale, rank them by share of search and find rising queries before you write.
  • Content calendars: with a year or more of data, see in which month (peakMonth) interest in a topic peaks and plan around it.
  • Trend monitoring: schedule a run and use trendDirection and changePercent to spot keywords that are rising or falling, without post-processing.
  • Market and brand research: compare brands, products or topics by country, state or city, and by search property such as YouTube or Google Shopping.
  • Product and seasonality planning: use five years of weekly data or the full history since 2004 to time launches and stock.
  • AI agents and automation: feed Google Trends data and trending searches into reports, alerts and agent workflows.

How the bulk comparison works

Google rescales every comparison so that its own highest point is 100, so two separate comparisons cannot be put side by side. With Compare all the Actor solves this for up to 200 keywords:

  1. Up to five keywords are compared by Google in a single request. They are already on one scale.
  2. With more than five keywords the Actor builds batches of one anchor keyword plus up to four new keywords. Every batch uses the same region, time range and filters.
  3. The anchor appears in every batch. The reference batch is the first batch where the anchor has a usable timeline with search volume (normally the first). Every other batch is multiplied by the sum of the anchor's values in the reference batch divided by the sum of the anchor's values in that batch.
  4. Finally everything is rescaled so the highest value across your keywords is 100, and values are rounded to two decimals. That is why values can have decimals when you compare more than five keywords.

Choose an anchor with steady, medium-to-high interest. Without anchorKeyword the first keyword is used. An anchor that is not in your keyword list is used for scaling only: it gets no result and is not charged. If the anchor has no measurable volume in a batch, that batch's keywords get status noData with a message suggesting a stronger anchor. If one batch fails, only its keywords are affected.

In our offline test, a keyword measured through an anchor matched a direct five-keyword comparison within about 0.25 index points on average. Keywords far below the strongest keyword register only as 0 or 1 on a common scale.

FAQ

How many keywords can I compare?

Up to 200 per run. Google compares five at a time, so larger lists are linked through the anchor keyword as described above. A run with 100 keywords and interest over time takes roughly 5 to 6 minutes with the default two sessions, and Google rate limiting can add time.

The numbers come from the same endpoints the website uses. The Actor adds what the website lacks: bulk comparison of up to 200 keywords on one scale, flat JSON, CSV and Excel output, an API, scheduling, and Trending now as a dataset. The website is interactive and compares five terms at a time. Values on a common scale across more than five keywords are estimates built with the anchor method. This Actor is not affiliated with or endorsed by Google.

Do the analysis fields cost extra?

No. The analysis fields are part of the same interest-over-time result, so there is no extra event, no extra input and no change in price. Results with status noData, blocked or error are still free, and their analysis fields are null.

Why are some analysis fields null?

null means the data to compute a field is not there, never zero. trendDirection, changePercent and recentAverage need at least 8 complete points. peakValue and peakTime are null when every complete point is 0. peakMonth needs data that covers all 12 calendar months, which the default 12 months of weekly data do, but a shorter range or an hourly range does not, and it is null for a flat series where every month has the same average. yearOverYearChangePercent and seasonalityIndex need two years (728 days), so use today 5-y or all for them. shareOfSearchPercent and compareRank need Compare all and a comparison that finished with no keyword blocked or error and some search volume. Every analysis field is null when status is not ok.

Can I schedule it?

Yes. Use Apify Schedules to run it hourly, daily or weekly, for example to track Trending now for a country or a fixed list of keywords. Each scheduled run is charged like any other run.

What does status "blocked" mean?

Google rate-limited or blocked the sessions of this run, so the keyword was not scraped. The result is free. Run it again later, or lower the number of parallel sessions. The Actor never attempts to solve CAPTCHAs or evade checks.

What does status "noData" mean?

Google has no data for the keyword with your filters because its search volume is too low. It also appears for keywords that are too small to register next to the others on a common scale.

The Actor reads public, aggregated, anonymous search-interest data. It collects no personal data, uses no login or cookies from user accounts, and does not fetch the Google Trends web pages that robots.txt excludes. You remain responsible for using the data in line with Google's terms and the laws that apply to you.

What happens if the platform migrates or restarts my run?

The run saves its progress after every finished keyword batch. After a migration it resumes where it stopped: finished results are not fetched, saved or charged again. When you compare more than five keywords, the finished batches are kept so the common scale is completed without repeating them. The trend analysis, share of search and rank are calculated from the final values once the comparison is complete, so a resumed run returns the same numbers as an uninterrupted one.

Not in this version. Google currently returns empty related-topic lists, so only related queries are offered.

What are the limits?

  • Values are Google's rounded 0-100 index, not search counts, and recent periods are marked isPartial.
  • Trending now results link no news articles except in the RSS fallback, which lists about 10 items.
  • The analysis fields describe Google's relative index, not search counts. Percent changes are only as precise as that index, and keywords with low interest can swing a lot.
  • Data starts in 2004, and Google decides the time resolution for the chosen range.
  • Google can change its internal endpoints at any time. Report problems through the Issues tab.

Changelog

  • 1.1 (2026-10-10): trend analysis fields on every interest-over-time result: peak value and time, recent average, change in percent, trend direction, year-over-year change, peak month and seasonality, plus share of search and compare rank when you compare keywords. Free, with no change in price or input.
  • 1.0 (2026-10-10): first release with interest over time, regions, related queries, Trending now, bulk compare of up to 200 keywords with anchor normalisation, migration-safe resume and pay-per-result pricing.