匹配范围
*://*.guazi.com/*guazi-used-car-detail用途 读取当前瓜子二手车公开详情页,返回当前车源的售价、里程、车龄、车况、过户、配置、车源地和详情页地址。 执行前提 请先打开瓜子二手车公开详情页,例如 https://www.guazi.com/car-detail/c<车源ID>.html。脚本读取当前页面 DOM,不需要登录。若页面出现安全验证、验证码或风控提示,需要先在真实浏览器会话中完成验证后再…
*://*.guazi.com/*dom.read1return await (async () => {2 const input = params && typeof params === "object" ? params : {};3 const clean = (value) => String(value == null ? "" : value).replace(/\s+/g, " ").trim();4 const sourceUrl = location.href;5 6 if (!/guazi\.com/.test(location.hostname) || !/\/car-detail\/c\d+\.html/.test(location.pathname)) {7 throw new Error("请先打开瓜子二手车公开详情页,例如 https://www.guazi.com/car-detail/c<车源ID>.html。");8 }9 10 const clueId = (sourceUrl.match(/car-detail\/c(\d+)/) || [])[1] || "";11 const expected = clean(input.clue_id || input.clueId || input.id || input.url);12 const expectedId = (expected.match(/car-detail\/c(\d+)/) || expected.match(/^c?(\d+)$/) || [])[1] || "";13 if (expectedId && expectedId !== clueId) {14 throw new Error(`当前详情页车源 ID 是 ${clueId},与参数 ${expectedId} 不一致。`);15 }16 17 const pageText = clean(document.body?.innerText || "");18 if (/瑞数|reese84|captcha|滑动验证|安全验证|验证码|访问过于频繁/i.test(pageText)) {19 throw new Error("瓜子二手车页面出现安全验证或访问频率限制,请先在真实浏览器会话中完成验证。");20 }21 22 const lines = (document.body?.innerText || "").split(/\n+/).map(clean).filter(Boolean);23 const meta = (name) => clean(document.querySelector(`meta[property="${name}"], meta[name="${name}"]`)?.getAttribute("content"));24 const afterLabel = (label) => {25 const index = lines.findIndex((line) => line === label);26 return index > 0 ? lines[index - 1] : "";27 };28 const beforeLabel = (label) => {29 const index = lines.findIndex((line) => line === label);30 return index >= 0 && index + 1 < lines.length ? lines[index + 1] : "";31 };32 const titleLine = lines.find((line) => line.length > 8 && !/首页|添加到桌面|下载APP|登录|车身外观|车况详解|本车卖点|检测报告/.test(line) && /款|版|型|L|EV|DM|T|CVT|自动|手动/.test(line)) || "";33 const title = titleLine || clean(document.title).replace(/^二手/, "").replace(/报价.*$/, "");34 const priceAmount = Number(meta("og:price:amount"));35 const price = Number.isFinite(priceAmount) && priceAmount > 0 ? `${(priceAmount / 10000).toFixed(2)}万` : "";36 37 const rows = [38 { field: "clue_id", value: clueId },39 { field: "title", value: title },40 { field: "price", value: price || beforeLabel("万") || "" },41 { field: "mileage", value: lines.find((line) => /万公里|公里/.test(line)) || "" },42 { field: "age", value: lines.find((line) => /\d+年\d+个月/.test(line)) || "" },43 { field: "condition_level", value: afterLabel("车况") || "" },44 { field: "condition", value: lines.find((line) => /基础车况/.test(line)) || "" },45 { field: "insurance_claims", value: lines.find((line) => /^理赔\d+次$/.test(line)) || "" },46 { field: "transfers", value: lines.find((line) => /^过户\d+次$/.test(line)) || "" },47 { field: "source_city", value: afterLabel("车源地") },48 { field: "color", value: afterLabel("车身颜色") },49 { field: "listing_no", value: afterLabel("车源编号") },50 { field: "engine", value: afterLabel("发动机") },51 { field: "gearbox", value: afterLabel("变速箱") },52 { field: "emission", value: afterLabel("排放标准") },53 { field: "drivetrain", value: afterLabel("驱动方式") },54 { field: "highlights", value: lines.slice(lines.indexOf("亮点配置") + 1, lines.indexOf("安全配置")).filter(Boolean).join(",") },55 { field: "url", value: sourceUrl },56 ];57 58 const hasUsefulData = rows.some((row) => row.field !== "clue_id" && row.field !== "url" && clean(row.value));59 if (!hasUsefulData) {60 throw new Error("没有从当前瓜子二手车详情页提取到车源信息,请确认页面已加载完成。");61 }62 63 return rows;64})();