灵猴市集Linghou Market

懂车帝车系评分

懂车帝dongchedi-series-score

用途 读取懂车帝车系公开页面的懂车分评分,返回综合、空间、动力、操控、舒适性、外观、内饰、配置 8 个维度,并附带同级车均值。 执行前提 需要在懂车帝网页中执行,建议打开目标车系页面,例如 https://www.dongchedi.com/auto/series/<id>。脚本读取公开页面数据,不需要登录。若未传入 seriesid,会尝试从当前页面 U…

评分懂车分车系
版本1.0.0
扫描passed
更新2026-06-28
超时30000ms

匹配范围

*://www.dongchedi.com/*

排除范围

未声明

能力声明

dom.read

代码

源码已展开
1return await (async () => {2  const DCD_BASE = "https://www.dongchedi.com";3  const FALLBACK_SHELL_KEYS = ["__hasUrlCity", "is_gray", "has_gray", "clientIp", "sensitiveSeriesIdList"];4  const AXES = [5    ["score", "综合"],6    ["space_score", "空间"],7    ["power_score", "动力"],8    ["control_score", "操控"],9    ["comfort_score", "舒适性"],10    ["appearance_score", "外观"],11    ["interiors_score", "内饰"],12    ["configuration_score", "配置"],13  ];14 15  const input = typeof params === "object" && params ? params : {};16 17  function clean(value) {18    return String(value == null ? "" : value).replace(/\s+/g, " ").trim();19  }20 21  function fail(message) {22    throw new Error(message);23  }24 25  function requireArray(value, label) {26    if (!Array.isArray(value)) {27      fail(`${label} 返回的数据结构不符合预期,应为数组。`);28    }29    return value;30  }31 32  function parseScore(raw) {33    const n = Number(raw);34    if (!Number.isFinite(n) || n <= 0) return null;35    return Number((n / 100).toFixed(2));36  }37 38  function normalizeSeriesId(rawInput) {39    const raw = clean(rawInput);40    const match = raw.match(/series\/(\d+)/) || raw.match(/^(\d+)$/);41    if (!match) {42      fail("series_id 必须是车系数字 ID,或包含 /auto/series/<id> 的链接。");43    }44    return match[1];45  }46 47  function currentSeriesId() {48    const match = String(location.href).match(/series\/(\d+)/);49    return match ? match[1] : "";50  }51 52  function extractPageProps(html) {53    const match = String(html || "").match(/<script id="__NEXT_DATA__"[^>]*>([\s\S]*?)<\/script>/);54    if (!match) return null;55    try {56      const data = JSON.parse(match[1]);57      return data && data.props && data.props.pageProps ? data.props.pageProps : null;58    } catch {59      return null;60    }61  }62 63  function isFallbackShell(pageProps) {64    if (!pageProps || typeof pageProps !== "object") return true;65    return Object.keys(pageProps).filter((key) => !FALLBACK_SHELL_KEYS.includes(key)).length === 0;66  }67 68  async function fetchPageProps(path, label) {69    const response = await fetch(`${DCD_BASE}${path}`, {70      credentials: "include",71      headers: { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" },72    });73    if (!response.ok) {74      fail(`${label} 请求失败:HTTP ${response.status}`);75    }76    const pageProps = extractPageProps(await response.text());77    if (!pageProps) {78      fail(`${label} 未返回页面数据,页面结构可能已变化或请求被拦截。`);79    }80    if (isFallbackShell(pageProps)) {81      fail(`${label} 返回空壳页面,车系 ID 可能不存在或页面入口已变化。`);82    }83    return pageProps;84  }85 86  function sameLevelAverage(reviewData) {87    const list = reviewData?.same_level_review;88    if (list == null) return reviewData?.average_series_review || {};89    requireArray(list, "同级车均值");90    return list.find((item) => String(item?.series_id) === "0") || list[0] || {};91  }92 93  function parseScoreBreakdown(scoreSimpleInfo, sameLevelAvg) {94    if (!scoreSimpleInfo || typeof scoreSimpleInfo !== "object" || Array.isArray(scoreSimpleInfo)) {95      fail("该车系暂无懂车分,可能是车主评价数量不足。");96    }97    const scoreInfo = scoreSimpleInfo || {};98    const avg = sameLevelAvg || {};99    return AXES.map(([key, label]) => ({100      dimension: label,101      score: parseScore(scoreInfo[key]),102      same_level_avg: parseScore(avg[key]),103    }));104  }105 106  const seriesId = normalizeSeriesId(input.series_id ?? input.seriesId ?? input.url ?? currentSeriesId());107  const pageProps = await fetchPageProps(`/auto/series/${seriesId}`, `车系评分 ${seriesId}`);108  const rows = parseScoreBreakdown(pageProps.scoreSimpleInfo, sameLevelAverage(pageProps.reviewData));109  if (rows.every((row) => row.score == null)) {110    fail("该车系暂无懂车分,可能是车主评价数量不足。");111  }112  return rows;113})();