灵猴市集Linghou Market

今日头条热榜新闻

今日头条toutiao-hot-news

今日头条热榜新闻 用途 读取今日头条首页热榜,返回热榜排名、标题、搜索词、热度、标签、页面地址和图片地址。 执行前提 先打开 https://www.toutiao.com/,再在当前标签页执行。热榜接口公开可访问,通常无需登录;若站点返回验证、限流、空结果或接口结构变化,脚本会直接报错,不会尝试绕过验证码、风控或访问限制。 参数 limit:可选,返回数…

热榜新闻
版本1.0.0
扫描passed
更新2026-06-28
超时30000ms

匹配范围

*://www.toutiao.com/*

排除范围

未声明

能力声明

dom.read

代码

源码已展开
1const rawParams = params && typeof params === "object" ? params : {};2 3function integerParam(name, fallback, min, max) {4  const raw = rawParams[name];5  const value = raw === undefined || raw === null || raw === "" ? fallback : Number(raw);6  if (!Number.isInteger(value) || value < min || value > max) {7    throw new Error(`${name} must be an integer between ${min} and ${max}`);8  }9  return value;10}11 12function assertToutiaoPage() {13  if (location.hostname !== "www.toutiao.com") {14    throw new Error("Open https://www.toutiao.com/ first, then run this script");15  }16}17 18function trimOrNull(value) {19  const text = String(value ?? "").trim();20  return text ? text : null;21}22 23function parseHotValue(value) {24  const number = Number(value);25  return Number.isFinite(number) && number >= 0 ? number : null;26}27 28function pickImage(item) {29  const direct = item?.Image?.url;30  if (typeof direct === "string" && direct) return direct;31 32  const list = Array.isArray(item?.Image?.url_list) ? item.Image.url_list : [];33  for (const entry of list) {34    const value = typeof entry === "string" ? entry : entry?.url;35    if (typeof value === "string" && value) return value;36  }37 38  return null;39}40 41function mapHotRow(item, index) {42  if (!item || typeof item !== "object") return null;43  const title = trimOrNull(item.Title);44  if (!title) return null;45  const groupId = trimOrNull(item.ClusterIdStr || (item.ClusterId !== undefined ? String(item.ClusterId) : null));46 47  return {48    rank: index + 1,49    group_id: groupId,50    title,51    query: trimOrNull(item.QueryWord) || title,52    hot_value: parseHotValue(item.HotValue),53    label: trimOrNull(item.Label),54    url: trimOrNull(item.Url),55    image_url: pickImage(item),56  };57}58 59async function readJson(response) {60  try {61    return await response.json();62  } catch {63    throw new Error("Response is not valid JSON");64  }65}66 67assertToutiaoPage();68const limit = integerParam("limit", 30, 1, 50);69 70const response = await fetch("https://www.toutiao.com/hot-event/hot-board/?origin=toutiao_pc", {71  headers: { Accept: "application/json" },72  credentials: "omit",73});74 75if (!response.ok) {76  throw new Error(`Hot news request failed with HTTP ${response.status}`);77}78 79const payload = await readJson(response);80 81if (payload?.status && payload.status !== "success") {82  throw new Error(`Hot news request returned status=${payload.status}`);83}84 85if (payload?.error || payload?.message) {86  throw new Error(`Hot news request returned error: ${payload.error || payload.message}`);87}88 89const rows = (Array.isArray(payload?.data) ? payload.data : [])90  .map(mapHotRow)91  .filter(Boolean)92  .slice(0, limit);93 94if (rows.length === 0) {95  throw new Error("No hot news data returned");96}97 98return rows.map((row, index) => ({ ...row, rank: index + 1 }));