灵猴市集Linghou Market

汽车之家品牌车系列表

汽车之家autohome-brand-series

用途 读取汽车之家公开车系目录,按品牌中文名或 A-Z 首字母返回品牌下的车系列表。适合快速查询某个品牌的车系 ID、车系名称、指导价和相关页面链接。 执行前提 先打开汽车之家页面,建议使用 https://www.autohome.com.cn/。脚本会在浏览器页面主世界中请求 https://www.autohome.com.cn/grade/carh…

汽车品牌车系目录
版本1.0.0
扫描passed
更新2026-06-28
超时30000ms

匹配范围

*://*.autohome.com.cn/*

排除范围

未声明

能力声明

dom.read

代码

源码已展开
1return await (async () => {2  const input = typeof params === "object" && params !== null ? params : {};3  const rawBrand = typeof input.brand === "string" ? input.brand.trim() : "";4  const rawLimit = input.limit === undefined ? 20 : Number(input.limit);5 6  if (!rawBrand) {7    throw new Error("params.brand is required. Use a Chinese brand name or one A-Z initial.");8  }9 10  if (!Number.isFinite(rawLimit) || rawLimit <= 0) {11    throw new Error("params.limit must be a positive number.");12  }13 14  const limit = Math.min(Math.floor(rawLimit), 100);15  const isInitialQuery = /^[A-Za-z]$/.test(rawBrand);16  const queryText = rawBrand.replace(/\s+/g, "").toLowerCase();17  const initials = isInitialQuery18    ? [rawBrand.toUpperCase()]19    : "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");20 21  const cleanText = (value) =>22    String(value || "")23      .replace(/\s+/g, " ")24      .replace(/\u00a0/g, " ")25      .trim();26 27  const normalizeText = (value) => cleanText(value).replace(/\s+/g, "").toLowerCase();28 29  const absoluteUrl = (value) => {30    if (!value) return null;31    try {32      return new URL(value, window.location.href).href;33    } catch (error) {34      return null;35    }36  };37 38  const parseBrandDocument = (html, initial) => {39    const doc = new DOMParser().parseFromString(html, "text/html");40    const rows = [];41    const brands = [];42 43    for (const brandNode of Array.from(doc.querySelectorAll("dl[id]"))) {44      const brandId = brandNode.getAttribute("id") || null;45      const brandName = cleanText(46        brandNode.querySelector("dt div a")?.textContent ||47          brandNode.querySelector("dt a:last-of-type")?.textContent48      );49 50      if (!brandName) continue;51 52      const brandKey = normalizeText(brandName);53      const isBrandMatch =54        isInitialQuery ||55        brandKey === queryText ||56        brandKey.includes(queryText) ||57        queryText.includes(brandKey);58 59      if (!isBrandMatch) continue;60      brands.push({ brandId, brandName, initial });61 62      let makerName = brandName;63      const detailNode = brandNode.querySelector("dd");64      const children = detailNode ? Array.from(detailNode.children) : [];65 66      for (const child of children) {67        if (child.matches(".h3-tit")) {68          makerName = cleanText(child.textContent) || brandName;69          continue;70        }71 72        if (!child.matches("ul")) continue;73 74        for (const itemNode of Array.from(child.querySelectorAll("li[id^='s']"))) {75          if (rows.length >= limit) break;76 77          const seriesId = (itemNode.getAttribute("id") || "").replace(/^s/, "");78          const titleLink = itemNode.querySelector("h4 a[href]");79          const priceLink = itemNode.querySelector("a.red[href]");80          const reputationLink = Array.from(itemNode.querySelectorAll("a[href]")).find(81            (link) => link.textContent.includes("口碑") || link.href.includes("//k.autohome.com.cn/")82          );83          const forumLink = Array.from(itemNode.querySelectorAll("a[href]")).find((link) =>84            link.textContent.includes("论坛")85          );86          const text = cleanText(itemNode.textContent);87          let guidePrice = cleanText(priceLink?.textContent);88 89          if (!guidePrice && text.includes("指导价:暂无")) {90            guidePrice = "暂无";91          }92 93          rows.push({94            brandId,95            brandName,96            makerName,97            seriesId,98            seriesName: cleanText(titleLink?.textContent),99            guidePrice: guidePrice || null,100            seriesUrl: absoluteUrl(titleLink?.getAttribute("href")),101            priceUrl: absoluteUrl(priceLink?.getAttribute("href")),102            reputationUrl: absoluteUrl(reputationLink?.getAttribute("href")),103            forumUrl: absoluteUrl(forumLink?.getAttribute("href")),104            initial,105          });106        }107 108        if (rows.length >= limit) break;109      }110    }111 112    return { rows, brands };113  };114 115  const items = [];116  const matchedBrands = [];117  const searchedInitials = [];118 119  for (const initial of initials) {120    if (items.length >= limit) break;121    searchedInitials.push(initial);122 123    const response = await fetch(`https://www.autohome.com.cn/grade/carhtml/${initial}.html`, {124      credentials: "include",125    });126 127    if (!response.ok) {128      throw new Error(`Failed to fetch brand catalog for initial ${initial}: HTTP ${response.status}.`);129    }130 131    const html = await response.text();132    const parsed = parseBrandDocument(html, initial);133    items.push(...parsed.rows.slice(0, limit - items.length));134 135    for (const brand of parsed.brands) {136      if (!matchedBrands.some((item) => item.brandId === brand.brandId)) {137        matchedBrands.push(brand);138      }139    }140 141    if (!isInitialQuery && matchedBrands.length > 0) break;142  }143 144  return {145    query: rawBrand,146    limit,147    searchedInitials,148    matchedBrands,149    count: items.length,150    items,151  };152})();