devto 2026-08-27 원문 보기 ↗
Not affiliated with, endorsed by, or sponsored by Google LLC. "Google" and "Google Trends" are trademarks of Google LLC, used here only to describe the public data discussed.
If you have ever built anything on top of "Trending Now" (a newsletter, an alerting bot, a content calendar), you know the uncomfortable part: a ranked list tells you what is trending, not for how long. A two-hour celebrity spike and a two-day story that is still growing look identical at rank 3.
Google's own Trending Now page actually knows the difference. Each trend has a start time and, once it stops trending, an end time. The interface shows a small "Active" / "Lasted N hours" label and moves on. Most tools that re-publish the feed drop that information on the floor.
This post is about keeping it, what the numbers look like once you do, and the limits of the approach.
For each trending term, keep four fields:
| field | meaning |
|---|---|
started_at |
Unix timestamp when the term entered the trending feed |
ended_at |
Unix timestamp when it left, or null while it is still trending |
is_active |
true while ended_at is null
|
duration_minutes |
ended_at - started_at, in minutes, once the trend has ended |
Everything else (volume, category, rank) is the same data every list gives you. These four turn a list into a lifecycle.
Measured on one live pull of the US feed, 24-hour window:
GB, 48-hour window: 530 of 615 terms had already ended by the time of the pull.
So: most of what is "trending right now" has already finished trending. If your pipeline reacts to the list once a day, roughly 70% of what it reacts to is over. Filtering on is_active == true is the single cheapest improvement you can make to a trend-driven workflow. Sorting the ended ones by duration_minutes is the second: it separates the stories with legs from the spikes.
We maintain a small Apify Actor that returns the Trending Now feed with these four fields on every row: Google Trends Scraper. Disclosure: it is our paid tool (pay-per-event: $0.01 per run plus $0.0005 per row on the free Apify tier; a run that returns zero rows costs nothing), so weigh the recommendation accordingly. The idea itself works with any source that exposes start and end times for a trend.
One synchronous request, results back as JSON:
curl -X POST \
"https://api.apify.com/v2/acts/orbots~google-trends-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"mode": "trending", "trendingGeos": ["US"], "trendingHours": 24}'
A row looks like this:
{
"term": "japan earthquake",
"rank": 3,
"geo": "US",
"started_at": 1785224400,
"ended_at": 1785238800,
"is_active": false,
"duration_minutes": 240,
"search_volume": 200000,
"formatted_volume": "200K+",
"category": "Law and Government",
"trends_url": "https://trends.google.com/trends/explore?q=japan+earthquake&date=now+1-d&geo=US&hl=en-US"
}
And the ten longest-lived ended trends, in Python:
import os
import requests
r = requests.post(
"https://api.apify.com/v2/acts/orbots~google-trends-scraper/run-sync-get-dataset-items",
params={"token": os.environ["APIFY_TOKEN"]},
json={"mode": "trending", "trendingGeos": ["US"], "trendingHours": 24},
timeout=300,
)
r.raise_for_status()
rows = r.json()
live = [x for x in rows if x["is_active"]]
ended = sorted((x for x in rows if not x["is_active"]),
key=lambda x: x["duration_minutes"], reverse=True)
print(f"{len(live)} active, {len(ended)} ended")
for x in ended[:10]:
print(f'{x["term"]:<32} {x["duration_minutes"]:>5} min {x["formatted_volume"]}')
run-sync-get-dataset-items blocks until the run finishes (three countries came back in 26 seconds in our benchmark) and returns the dataset directly, so there is no polling loop to write.
A daily schedule against a trending feed has a built-in waste problem: most of today's list was also on yesterday's. The Actor has an onlyNew flag that remembers, per country and window, which (term, start time) pairs it has already delivered to you, and returns only the additions. A topic that starts trending again later counts as new, because the key includes the start time. A day with nothing new ends as a successful run with zero rows, and zero charge.
If you are building the memory yourself, that key (term plus started_at) is the detail that matters. Keying on the term alone swallows every comeback.
200K+), not an absolute count. It is comparable across terms in the same feed; it is not a keyword-research number.ended_at is a snapshot pretending to be a stream.is_active, sort on duration_minutes, key your memory on (term, started_at).Data is public, aggregated search interest; no personal data is involved.
orbots builds small, reliable data Actors on Apify.