google-trends-now
v1.1.1
Published
Unofficial CLI and Node.js client for Google Trends Trending Now, with RSS fallback.
Downloads
97
Maintainers
Readme
google-trends-now
English | 简体中文
Unofficial CLI and Node.js client for Google Trends Trending Now, with an RSS fallback. Zero runtime dependencies.
Not an official Google client. It reads the current Trending Now web data path and falls back to Google Trends RSS when that path fails. RSS is a limited best-effort fallback, not the full Trending Now pool. Google's official Trends API alpha targets scaled search-interest data and does not yet cover this hot-word discovery use case.

Live snapshot — npx google-trends-now trending --geo US --hours 48 --sort volume --limit 5 --format json | jq '...'. Actual output changes with the news cycle.
Install
Requires Node.js >= 22 (built-in fetch, AbortSignal.timeout, Array.prototype.toSorted).
npm install google-trends-nowCLI
google-trends-now trending --geo US --hours 48 --format json
google-trends-now trending --category technology --status active --format ndjson
google-trends-now rss --geo US --format json
google-trends-now categories
google-trends-now healthcheck| Option | Values | Default |
|---|---|---|
| --geo | country/region code | US |
| --hours | 4 24 48 168 | 48 |
| --category | alias or numeric id | all |
| --status | all active ended | all |
| --sort | relevance volume recency title | relevance |
| --limit | integer or all (no truncation) | 100 |
| --format | json ndjson csv markdown | json |
| --hl | locale | en |
| --fallback | rss none | rss |
| --timeout-ms | integer | 30000 |
| --retries | integer; retry transient 429/5xx/network failures | 0 |
| --include-raw | flag; attach the pre-normalization batchexecute payload as raw (json format only) | off |
| --with-news | integer 1-10; resolve news articles for the first n items into a news field (trending command, json format only) | off |
| -h, --help · -v, --version | | |
Category filtering is always applied locally against each row's categories[]; the request-side category is only an upstream hint. Unknown categories and misspelled flags (e.g. --categroy) fail fast rather than being silently ignored.
--retries opts into a restrained retry that only covers transient 429/5xx/network failures (a 429 honors Retry-After, capped at 30s); it is a defense against a single blip, not a way to grind past rate limiting. --include-raw and --with-news require --format json and fail fast otherwise.
- Exit codes:
0success ·1healthcheck not-ok ·2usage/validation/runtime error. healthcheckprobes the primary endpoint only (forces--fallback none, so RSS can't mask an outage) and always prints JSON{ ok, elapsed_ms, fetch_status, source, error, item_count }.okistrueonly onfetch_status: "success"with at least one item; the process exits0/1accordingly.categoriesprints the alias table and honors--format; itsjsonoutput is a bare[{ alias, id, name }]array, not the result envelope.
SDK
import { fetchTrendingNews, fetchTrendingNow, fetchTrendingRss, formatMarkdown } from "google-trends-now";
const output = await fetchTrendingNow({
geo: "US",
hours: 48,
category: "technology",
status: "active",
limit: 25
});
console.log(formatMarkdown(output));
const news = await fetchTrendingNews(output.items[0].news_refs.slice(0, 5));
console.log(news[0]?.title); // resolved article headline
const rss = await fetchTrendingRss({ geo: "US", limit: 10 });
console.log(rss.fetch_status); // "rss_limited"Also exported: categories, categoryRows, normalizeTrendingRow, formatJson, formatNdjson, formatCsv, parseTrendingRssXml, and the low-level batchexecute helpers. Full field types ship in the bundled index.d.ts.
Output schema
fetchTrendingNow(options) resolves to an envelope:
{
observed_at: "2026-07-06T00:00:00.000Z",
geo: "US", hours: 48, category: "all", status: "all", sort: "relevance",
source: "google_trending_now", // or "rss_limited"
fetch_status: "success", // or "rss_limited" | "manual_review_required"
source_url: "https://trends.google.com/trending?geo=US&hl=en&hours=48",
error: null,
items: [ /* ... */ ]
}category_filter_status / status_filter_status are optional keys added only on RSS output when a category/status filter was requested (see RSS fallback); they are absent on the normal path.
Each item:
{
position: 1, raw_position: 1,
query: "example trend", normalized_query: "example trend",
search_volume: 50000, search_volume_label: "50000+",
increase_percentage: 200,
started_at: "2026-07-06T00:00:00.000Z", ended_at: null,
start_timestamp: 1783296000, end_timestamp: null,
active: true,
trend_breakdown: ["example trend"],
categories: [{ id: 18, name: "Technology" }],
explore_url: "https://trends.google.com/trends/explore?...",
source: "google_trending_now"
}Formats
| Format | Output |
|---|---|
| json | full envelope |
| ndjson | one normalized item per line |
| csv | flat rows; categories and breakdown joined by ; (formula-injection safe) |
| markdown | compact report table |
RSS fallback
When the Trending Now request fails and --fallback rss is on, the client fetches https://trends.google.com/trending/rss?geo=<geo> and marks the output source: "rss_limited", fetch_status: "rss_limited".
RSS lacks the category, active-status, and full trend-pool fields of Trending Now, so it is best-effort only. If a category/status filter was requested, the rows are kept and flagged with category_filter_status/status_filter_status: "unavailable_in_rss".
Disclaimer & license
Google Trends numbers are approximate search-interest signals: volume labels are not sales, demand, or market size, and trending rank is not opportunity rank. The internal endpoint is undocumented and may change, throttle, or require manual review; this package uses no browser automation, login, proxy rotation, or CAPTCHA bypass.
MIT licensed (LICENSE). "Google" and "Google Trends" are trademarks of Google; this project is unofficial and not endorsed by Google.
Development
npm test # node --test, no network
npm run lint # eslint (flat config)
node bin/google-trends-now.mjs categories # offline smoke check
npx . trending --geo US --limit 5 # run from a checkout
npm pack --dry-run # inspect the publishable tarballSee CONTRIBUTING.md, SECURITY.md, and CHANGELOG.md.
Releasing
Releases are cut manually (low release cadence does not justify automation):
- Bump
versioninpackage.jsonand date the## Unreleasedsection inCHANGELOG.md; commit and tagvX.Y.Z. npm publish—prepublishOnlyruns the tests and lint automatically.
简体中文
非官方 Google Trends Trending Now 命令行工具和 Node.js SDK,带 RSS 兜底。零运行时依赖。
不是 Google 官方客户端。它优先读取当前 Trending Now 网页数据路径,失败时降级读取 Google Trends RSS。RSS 只是有限的 best-effort 兜底,不是完整 Trending Now 池。Google 官方 Trends API alpha 面向可缩放的搜索兴趣数据,暂不覆盖本项目的热词发现用途。
安装
需要 Node.js >= 22(内置 fetch、AbortSignal.timeout、Array.prototype.toSorted)。
npm install google-trends-now命令行
google-trends-now trending --geo US --hours 48 --format json
google-trends-now trending --category technology --status active --format ndjson
google-trends-now rss --geo US --format json
google-trends-now categories
google-trends-now healthcheck| 参数 | 取值 | 默认 |
|---|---|---|
| --geo | 国家/地区代码 | US |
| --hours | 4 24 48 168 | 48 |
| --category | 别名或数字 id | all |
| --status | all active ended | all |
| --sort | relevance volume recency title | relevance |
| --limit | 整数或 all(不截断) | 100 |
| --format | json ndjson csv markdown | json |
| --hl | 语言 locale | en |
| --fallback | rss none | rss |
| --timeout-ms | 整数 | 30000 |
| --retries | 整数;对瞬时的 429/5xx/网络失败重试 | 0 |
| --include-raw | 布尔开关;在 json 输出的信封上附加 normalize 前的原始 batchexecute payload(raw 字段,仅 json 格式) | 关 |
| --with-news | 整数 1-10;为前 n 条结果解析新闻文章并写入 news 字段(仅 trending 命令 + json 格式) | 关 |
| -h, --help · -v, --version | | |
分类过滤一定基于每条结果返回的 categories[] 在本地执行;请求参数里的分类只是上游提示。未知分类和拼错的参数(例如 --categroy)会直接报错,而不是被静默忽略。
--retries 开启的是克制的重试,只覆盖瞬时的 429/5xx/网络失败(429 会尊重 Retry-After,封顶 30 秒),用于抵抗单次抖动,而不是绕过限流。--include-raw 和 --with-news 都要求 --format json,否则直接报错。
- 退出码:
0成功 ·1healthcheck not-ok ·2用法/校验/运行时错误。 healthcheck只探测主接口(内部强制--fallback none,RSS 兜底不会掩盖故障),并且始终输出 JSON{ ok, elapsed_ms, fetch_status, source, error, item_count }。只有fetch_status: "success"且至少一条结果时ok才为true,进程据此退出0/1。categories打印分类别名表并支持--format;它的json输出是裸数组[{ alias, id, name }],不是结果包。
SDK
import { fetchTrendingNow, fetchTrendingRss, formatMarkdown } from "google-trends-now";
const output = await fetchTrendingNow({
geo: "US",
hours: 48,
category: "technology",
status: "active",
limit: 25
});
console.log(formatMarkdown(output));
const rss = await fetchTrendingRss({ geo: "US", limit: 10 });
console.log(rss.fetch_status); // "rss_limited"另外导出:categories、categoryRows、normalizeTrendingRow、formatJson、formatNdjson、formatCsv、parseTrendingRssXml,以及底层 batchexecute 辅助函数。完整字段类型见随包发布的 index.d.ts。
输出结构
fetchTrendingNow(options) 返回一个结果包:
{
observed_at: "2026-07-06T00:00:00.000Z",
geo: "US", hours: 48, category: "all", status: "all", sort: "relevance",
source: "google_trending_now", // 或 "rss_limited"
fetch_status: "success", // 或 "rss_limited" | "manual_review_required"
source_url: "https://trends.google.com/trending?geo=US&hl=en&hours=48",
error: null,
items: [ /* ... */ ]
}category_filter_status / status_filter_status 是可选字段,仅在使用 RSS 且请求了 category/status 过滤时出现(见 RSS 兜底),正常路径上不会有。
单条结果:
{
position: 1, raw_position: 1,
query: "example trend", normalized_query: "example trend",
search_volume: 50000, search_volume_label: "50000+",
increase_percentage: 200,
started_at: "2026-07-06T00:00:00.000Z", ended_at: null,
start_timestamp: 1783296000, end_timestamp: null,
active: true,
trend_breakdown: ["example trend"],
categories: [{ id: 18, name: "Technology" }],
explore_url: "https://trends.google.com/trends/explore?...",
source: "google_trending_now"
}输出格式
| 格式 | 输出 |
|---|---|
| json | 完整结果包 |
| ndjson | 每行一条标准化结果 |
| csv | 扁平表格;分类名和 breakdown 用 ; 连接(已防 CSV 公式注入) |
| markdown | 适合报告的紧凑表格 |
RSS 兜底
当 Trending Now 请求失败且启用 --fallback rss 时,客户端会请求 https://trends.google.com/trending/rss?geo=<geo>,并把输出标记为 source: "rss_limited"、fetch_status: "rss_limited"。
RSS 不含 Trending Now 的分类、活跃状态和完整趋势池字段,只能作为 best-effort 兜底。如果请求了 category/status 过滤,结果会保留并标记 category_filter_status/status_filter_status: "unavailable_in_rss"。
免责声明与协议
Google Trends 数值是近似搜索兴趣信号:搜索量标签不等于销量、需求或市场规模,Trending rank 也不等于机会排序。内部接口没有官方文档,可能变化、限流或需要人工复核;本项目不使用浏览器自动化、登录、代理轮换或验证码绕过。
MIT 协议(LICENSE)。"Google"、"Google Trends" 是 Google 的商标;本项目为非官方项目,未获 Google 背书。
开发
npm test # node --test,无网络
node bin/google-trends-now.mjs categories # 离线冒烟检查
npx . trending --geo US --limit 5 # 在源码仓库中直接运行
npm pack --dry-run # 查看可发布 tarball