灵猴市集Linghou Market

雪球股票搜索

雪球xueqiu-stock-search

雪球股票搜索 用途 按股票代码或名称搜索雪球股票,返回匹配股票的代码、名称、交易所、价格、涨跌幅、行业、交易状态和雪球页面地址。 执行前提 先打开 https://xueqiu.com/ 或雪球站内页面。请求会使用当前浏览器 Cookie;接口可能受登录态、风控、Cookie 状态和访问频率影响,脚本不会绕过登录、验证码或风控。 参数 query:必填,股…

股票搜索行情
版本1.0.0
扫描passed
更新2026-06-28
超时30000ms

匹配范围

*://xueqiu.com/**://*.xueqiu.com/*

排除范围

未声明

能力声明

dom.read

代码

源码已展开
1const rawParams = typeof params === "object" && params !== null ? params : {};2 3function assertXueqiuPage() {4  if (!/(^|\.)xueqiu\.com$/i.test(location.hostname)) {5    throw new Error("请先打开 xueqiu.com 页面再执行脚本");6  }7}8 9function readQuery() {10  const query = String(rawParams.query ?? "").trim();11  if (!query) {12    throw new Error("query 为必填参数,请输入股票代码或名称");13  }14  return query;15}16 17function readLimit() {18  const value = rawParams.limit ?? 10;19  const limit = Number(value);20  if (!Number.isInteger(limit) || limit < 1 || limit > 50) {21    throw new Error("limit 必须是 1 到 50 的整数");22  }23  return limit;24}25 26function firstValue() {27  for (const value of arguments) {28    if (value !== undefined && value !== null && value !== "") return value;29  }30  return null;31}32 33function numericOrText(value) {34  if (value === undefined || value === null || value === "") return null;35  const number = Number(value);36  return Number.isFinite(number) ? number : String(value);37}38 39function normalizeSymbol(stock) {40  const rawCode = String(firstValue(stock.code, stock.symbol, "")).trim().toUpperCase();41  if (!rawCode) return "";42  if (/^(SH|SZ|BJ)[0-9A-Z.]+$/i.test(rawCode)) return rawCode;43 44  const exchange = String(firstValue(stock.exchange, stock.market, "")).trim().toUpperCase();45  const prefixMap = {46    SH: "SH",47    SSE: "SH",48    SHSE: "SH",49    XSHG: "SH",50    SZ: "SZ",51    SZSE: "SZ",52    XSHE: "SZ",53    BJ: "BJ",54    BSE: "BJ",55    XBEI: "BJ",56  };57  const prefix = prefixMap[exchange];58  if (prefix && /^[0-9]{6}$/.test(rawCode)) return `${prefix}${rawCode}`;59  return rawCode;60}61 62async function readJson(response) {63  try {64    return await response.json();65  } catch {66    return null;67  }68}69 70function errorDetail(payload, fallback) {71  return firstValue(payload?.error_description, payload?.errorMessage, payload?.message, fallback);72}73 74assertXueqiuPage();75 76const query = readQuery();77const limit = readLimit();78const url = `https://xueqiu.com/stock/search.json?code=${encodeURIComponent(query)}&size=${encodeURIComponent(limit)}`;79 80const response = await fetch(url, {81  headers: { Accept: "application/json" },82  credentials: "include",83});84 85const payload = await readJson(response);86 87if (!response.ok) {88  throw new Error(`请求雪球股票搜索失败:${errorDetail(payload, `HTTP ${response.status}`)}`);89}90 91if (payload?.error_code || payload?.error_description) {92  throw new Error(`请求雪球股票搜索失败:${errorDetail(payload, payload.error_code)}`);93}94 95const stocks = Array.isArray(payload?.stocks) ? payload.stocks : [];96if (!stocks.length) {97  throw new Error(`没有找到与“${query}”匹配的股票`);98}99 100return stocks.slice(0, limit).map((stock, index) => {101  const symbol = normalizeSymbol(stock);102  return {103    rank: index + 1,104    symbol,105    name: firstValue(stock.name, stock.stock_name, stock.title),106    exchange: firstValue(stock.exchange, stock.market),107    price: numericOrText(firstValue(stock.current, stock.price, stock.last)),108    changePercent: numericOrText(firstValue(stock.percentage, stock.percent, stock.change_percent, stock.changePercent)),109    industry: firstValue(stock.industry, stock.industry_name, stock.industryName),110    marketStatus: firstValue(stock.market_status, stock.marketStatus, stock.status),111    url: symbol ? `https://xueqiu.com/S/${symbol}` : null,112  };113});