Google Trends Scraper - Interest, Regions & Related Queries avatar

Google Trends Scraper - Interest, Regions & Related Queries

Pricing

from $0.06 / 1,000 google trends rows

Go to Apify Store
Google Trends Scraper - Interest, Regions & Related Queries

Google Trends Scraper - Interest, Regions & Related Queries

Every Google Trends number is relative: 100 is that keyword's own peak in the window you asked for, not a volume. Interest over time, interest by region, top and rising related queries. Up to 25 keywords, no API key. $0.06 per 1,000 rows, flat on every plan.

Pricing

from $0.06 / 1,000 google trends rows

Rating

0.0

(0)

Developer

Dami's Studio

Dami's Studio

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

2 days ago

Last modified

Categories

Share

Google Trends Scraper

Type keywords, get Google Trends back as flat rows: interest over time, interest by region, and the top and rising related queries. One row per datapoint, ready to drop into a spreadsheet, a database or a chart. It also pulls the Trending Now list for any country.

No account, no API key, no cookies, no browser.

  • Up to 25 keywords per run, each scaled 0-100 against its own peak, the same numbers Google Trends shows you.
  • Three data sets per keyword. Tick only the ones you want and pay for nothing else.
  • Every region Google supports: a country code like US, GB, DE or IN, a sub-region like US-CA, or worldwide.
  • Time ranges from the past hour to 2004-to-now, plus any custom date range you type.
  • Comparison mode puts up to five keywords on one shared scale, like typing several terms into Google Trends at once.
  • Trending Now for any country, with the top news story behind each spike.

Price

$0.06 per 1,000 rows, plus a $0.001 start fee per run (billed per gigabyte of run memory, so exactly that on the default 1 GB).

That $0.06 doesn't move with your plan or your volume. No tiers to climb, no minimum spend, nothing charged monthly.

RowsTotal cost
100$0.007
1,000$0.061
10,000$0.601
100,000$6.001

What is actually charged

  • One trend-scraped event per row written to the dataset. Nothing else is metered per row.
  • Free: the sample row an empty run returns, and every diagnostic row, whether that's a keyword with no data, a rate-limited request or a region Google doesn't publish. They carry "charged": false.
  • Datapoints Google marks as having no data are dropped before they're charged, so a keyword with thin volume costs you nothing for the empty part of the series.
  • Ask for city-level detail in a region where Google has none and the run falls back to the level Google does publish. You're charged for the rows you get, never for the attempt.
  • A run that finds nothing costs the start fee and nothing more.
  • One row, one charge, and both are countable. The billing event has its own name, so nothing is priced onto Apify's generic per-item event where you wouldn't think to look for it.

Input

{
"searchTerms": ["bitcoin", "ethereum"],
"geo": "US",
"timeframe": "today 12-m",
"dataTypes": ["interestOverTime", "interestByRegion", "relatedQueries"],
"maxItems": 500
}
FieldWhat it does
searchTermsThe keywords or phrases to look up. Up to 25 per run. Each is looked up on its own and scaled 0-100 against its own peak.
geoTwo-letter country code (US, GB, DE, IN, BR), a sub-region (US-CA, GB-ENG), or empty for worldwide.
timeframeOne of now 1-H, now 4-H, now 1-d, now 7-d, today 1-m, today 3-m, today 12-m, today 5-y, all, or a custom range typed as 2024-01-01 2024-12-31.
dataTypesAny of interestOverTime, interestByRegion, relatedQueries. Drop the ones you don't need and the bill drops with them.
maxItemsTotal rows across every keyword and data set. Budget roughly 150 rows per keyword when all three data sets are on. Default 1,000, hard ceiling 20,000.
compareKeywordsOff by default. Turn it on to put the first five keywords on one shared scale so their interest-over-time values can be compared directly.
searchTypeweb, images, news, youtube or shopping. Which Google surface the interest is measured on.
regionLeveldefault, country, region, city or metro. city and metro produce far more rows; when Google has no data at that level the run falls back to the level it does publish.
categoryOptional Google Trends category id, for example 71 for Food & Drink or 7 for Finance. 0 means all categories.
languageLanguage code for region names and labels, like en-US, de or ja. It changes spelling, not data.
trendingNowGeosOptional country codes for the Trending Now list. Independent of the keywords, and usable on its own.
proxyUrlsLeave empty. Fill it in only if you want the traffic to leave through proxy servers you already pay for.

Leave the input empty and you get one labelled sample row for nothing, so you can see the shape before you spend.

Output

One row per datapoint. Real row from a real run:

{
"ok": true,
"charged": true,
"keyword": "bitcoin",
"geo": "US",
"timeframe": "today 12-m",
"searchType": "web",
"category": 0,
"trendsUrl": "https://trends.google.com/trends/explore?q=bitcoin&date=today+12-m&geo=US",
"recordType": "interest_over_time",
"date": "2025-08-17T00:00:00.000Z",
"dateLabel": "Aug 17, 2025",
"value": 29,
"formattedValue": "29",
"isPartial": false,
"scrapedAt": "2026-08-20T19:53:13.168Z"
}

Field notes

  • recordType — which of the four kinds of row this is: interest_over_time, interest_by_region, related_query or trending_now. Filter on it to split the dataset into its parts.
  • value — Google's own 0-100 relative interest number. 100 is the peak of the series you asked for, not an absolute search volume. Google never publishes absolute volumes.
  • formattedValue — the label Google shows next to the value. For rising related queries this is where Breakout and +450% appear, which the numeric value can't express.
  • date — ISO 8601 in UTC, on interest_over_time rows and on the publication time of a trending_now row. Null on regional and related-query rows.
  • dateLabel — the same instant as Google prints it on the chart axis, kept because a weekly point covers a range the timestamp alone hides.
  • isPartial — true on the final point of a series, where the period hasn't finished and the value will still move. Drop those rows before charting a trend line.
  • geoName — the region name in your chosen language, on interest_by_region rows. geoCode carries the machine-readable code where Google publishes one.
  • latitude / longitude — only on city-level regional rows, where Google returns coordinates instead of a region code.
  • relatedQuery — the related search, on related_query rows. queryType is top (consistently searched alongside your keyword) or rising (growing fastest right now), and rank is its position, 1 being the strongest.
  • trendsUrl — the Google Trends page the row came from, so any number can be checked by eye in one click.
  • trafficEstimate — on trending_now rows only. The approximate search count Google publishes for the spike, such as 20K+.

How it works

It talks to the same JSON endpoints the Google Trends website calls, and asks for only the data sets you ticked. No page rendering, no headless browser, no login, no API key.

The endpoint hands any first-time visitor a short-lived guest session before it will answer. The run mints its own, keeps it for the run, and throws it away at the end. Nothing is stored between runs and no account is involved.

Requests leave through a large pool of rotating addresses. Google throttles per address, so when one is throttled the run continues from the next rather than waiting, and because the data request isn't tied to the address that opened it, nothing has to be redone.

Every response is parsed straight into flat rows. A datapoint Google marks as empty is dropped before it becomes a row, so you're never billed for a gap in the series.

The Trending Now list comes from Google's own public feed for that country, which needs no session at all.

The four kinds of row

Everything is one flat table, and recordType says which part of Google Trends a row came from.

  • interest_over_time — one row per point on the chart, with date, dateLabel, value and isPartial. A 12-month range gives about 53 weekly points; the past day gives minute-level points; all gives monthly points back to 2004.
  • interest_by_region — one row per region, with geoName, geoCode and value. Worldwide runs break down by country; a single country breaks down by state or province, or by city or metro area if you ask.
  • related_query — one row per related search, with relatedQuery, queryType (top or rising), rank, value and formattedValue. Up to 25 of each per keyword.
  • trending_now — one row per search spiking right now in the country you asked for, with rank, trafficEstimate and the top news story behind it.

Because it's one table, keyword, geo, timeframe, searchType and category repeat on every row. That's deliberate. You can filter or group the dataset without joining anything back together.

Diagnostic rows

Nothing here fails silently, and a failed run never bills you for the failure. A problem becomes a row carrying "_diagnostic": true, "charged": false and an errorCode: NO_RESULTS when Google has no data for a keyword in that region and range, RATE_LIMITED when Google throttled a request the run couldn't recover, BLOCKED when a request was refused, TIME_BUDGET when the run ran out of time before reaching a keyword, NETWORK when the target couldn't be reached. Each carries a plain-English error and the keyword or geo it belongs to.

The free sample row is tagged "_sample": true and only turns up when the run was given no keywords and no trending-now regions. Filter on charged == true for the data alone; the count of those rows is the number of events you were billed for.

What the 0-100 number actually means

Google Trends never publishes absolute search volumes. Every value is relative: 100 is the highest point of the exact series you asked for, and everything else is scaled against it. Change the time range, the region or the category and the whole series is rescaled.

Two consequences worth knowing before you build on it.

  1. Two separate runs are not directly comparable. "bitcoin" at 100 and "ethereum" at 100 in two runs does not mean they're equally searched. Each was scaled against its own peak. When you need them on one scale, turn on compareKeywords and run them together.
  2. A keyword with low volume returns little or nothing. Google suppresses series it considers too sparse, and you get an uncharged NO_RESULTS row rather than a flat line of zeroes. Broaden the region, lengthen the time range, or use a more common phrasing.

Limitations

  • Related TOPICS aren't offered. Google returns an empty list for that widget to callers who aren't signed in, so shipping the field would mean shipping a column that's always empty. Related QUERIES, top and rising, are unaffected and come back in full.
  • Values are Google's relative 0-100 index, never absolute search volumes. Nobody can scrape absolute volumes from Google Trends, because Google doesn't publish them.
  • A series is rescaled whenever the region, time range or category changes, so numbers from runs with different settings can't be compared point-for-point.
  • Keywords with low search volume return no data at all rather than low numbers. You get an uncharged diagnostic row saying so.
  • The final point of a series is usually partial, flagged with isPartial: true. It will move if you re-run later in the day.
  • City-level and metro-level breakdowns are best-effort. Google publishes dense city data for high-volume terms in large countries and nothing at all in many other combinations. When there's nothing, the run falls back to the level Google does publish. Metro areas are United States only.
  • Comparison mode takes at most five keywords, which is Google's own limit. Extra keywords are dropped with a warning.
  • The Trending Now list is whatever Google currently publishes for that country, typically around ten entries, and it's a live snapshot. Two runs an hour apart will differ.
  • Google throttles heavy use per address. The run answers a throttle by continuing from a different address, but a very large run can still end with some keywords carrying an uncharged RATE_LIMITED row instead of data.
  • Hard ceilings: 25 keywords per run, 20 trending-now regions per run, 20,000 rows per run.
  • Category ids are Google's own numeric ids. There's no lookup built in. Pick the number off a Google Trends URL when you narrow a search by category there.

Questions

Do I need a Google account or an API key?

No. The run mints its own short-lived guest session against Google's public endpoints and discards it when it finishes. No account is created, no credentials are stored, nothing carries over between runs.

Why does one keyword produce so many rows?

Because the output is flat. A single keyword with all three data sets over twelve months is about 53 interest-over-time points, about 50 regions and up to 50 related queries, so roughly 150 rows. That's the same data Google shows you on one page, unpacked so it can be sorted, filtered and charted without parsing. For fewer rows, untick data sets in dataTypes or lower maxItems.

Can I compare two keywords directly?

Set compareKeywords to true and put both in searchTerms. Up to five keywords are then put on one shared 0-100 scale so their value numbers read against each other. Leave it off and each keyword is scaled against its own peak instead.

What happens if a keyword has no data?

One uncharged diagnostic row for it with errorCode: "NO_RESULTS", and the run carries on to your other keywords.

Will the run fail if Google throttles it?

No. A throttled request is retried from a different address automatically. If a data set still can't be fetched you get an uncharged RATE_LIMITED diagnostic row for it and the run finishes as succeeded. Failing the run would just charge you a start fee to be told Google was busy.

Can I run this on a schedule?

Yes. Nothing is held between runs. Schedule the same input daily or weekly and use keyword plus recordType plus date as a key to work out what changed. Remember the last point of each series is partial and will move.

Do I need a proxy?

No, and there's nothing to configure. Egress is included in the rate above. proxyUrls is there only for people who already pay for their own servers and want the traffic to leave through those.