灵猴市集Linghou Market

新浪财经滚动新闻

新浪财经sinafinance-rolling-news

新浪财经滚动新闻提取 用途 读取新浪财经滚动新闻页中已经渲染出的新闻列表,返回栏目、标题、时间和新闻地址。 执行前提 先打开 https://finance.sina.com.cn/roll/#pageid=384&lid=2519 滚动新闻页,再执行脚本。页面公开可访问,通常无需登录;新闻列表可能由页面脚本异步填充,若页面显示验证、加载失败或列表为空,脚…

新闻滚动内容提取
版本1.0.0
扫描passed
更新2026-06-28
超时30000ms

匹配范围

*://finance.sina.com.cn/roll*

排除范围

未声明

能力声明

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 sleep(ms) {13  return new Promise(resolve => setTimeout(resolve, ms));14}15 16function normalizeText(value) {17  return (value || "").replace(/\s+/g, " ").trim();18}19 20function assertRollingNewsPage() {21  const current = new URL(location.href);22  if (current.hostname !== "finance.sina.com.cn" || !current.pathname.startsWith("/roll")) {23    throw new Error("Open https://finance.sina.com.cn/roll/#pageid=384&lid=2519 first, then run this script");24  }25}26 27function detectBlockedPage(doc) {28  const text = normalizeText(`${doc.title || ""} ${doc.body ? doc.body.innerText : ""}`).slice(0, 5000);29  if (/安全验证|验证码|人机验证|访问异常|请输入验证码|访问受限|页面加载失败/.test(text)) {30    return "The page is showing a verification or access-control challenge";31  }32  return "";33}34 35function trustedUrl(raw) {36  if (!raw) return "";37  try {38    const url = new URL(raw, location.href);39    if (url.protocol !== "http:" && url.protocol !== "https:") return "";40    return url.toString();41  } catch {42    return "";43  }44}45 46function extractNews(doc, limit) {47  const rows = [];48  const items = doc.querySelectorAll(".d_list_txt li, #d_list li");49 50  for (const el of items) {51    if (rows.length >= limit) break;52    const titleEl = el.querySelector(".c_tit a") || el.querySelector("a[href]");53    const title = normalizeText(titleEl ? titleEl.textContent : "");54    const url = trustedUrl(titleEl ? titleEl.getAttribute("href") || titleEl.href : "");55    if (!title || !url) continue;56 57    rows.push({58      rank: rows.length + 1,59      column: normalizeText(el.querySelector(".c_chl")?.textContent || ""),60      title,61      date: normalizeText(el.querySelector(".c_time")?.textContent || ""),62      url,63    });64  }65 66  return rows;67}68 69async function waitForNews(doc, limit) {70  const deadline = Date.now() + 10000;71  let rows = extractNews(doc, limit);72  while (Date.now() < deadline && rows.length === 0) {73    const blocked = detectBlockedPage(doc);74    if (blocked) throw new Error(`${blocked}; complete it in the browser and run again`);75    await sleep(250);76    rows = extractNews(doc, limit);77  }78  return rows;79}80 81const limit = integerParam("limit", 20, 1, 100);82assertRollingNewsPage();83 84const blocked = detectBlockedPage(document);85if (blocked) throw new Error(`${blocked}; complete it in the browser and run again`);86 87const items = await waitForNews(document, limit);88if (items.length === 0) {89  throw new Error("No rolling news rows found; the page may be empty, still loading, blocked, or its structure changed");90}91 92return items.slice(0, limit);