/** * SSR 数据提取器 - 淘宝/天猫页面内嵌 JSON * * 页面 HTML 里有完整商品数据挂在 window.__ICE_APP_CONTEXT__, * 包含标题、主图、SKU(图+名)、价格、参数,比 DOM 采集稳定 10 倍: * - 不受懒加载影响 * - 不受改版影响(JSON 结构远比 CSS 类名稳定) * - 一次拿全所有 SKU,无需滚动 * * 当前只支持淘宝/天猫(__ICE_APP_CONTEXT__), * 其他平台返回 null,触发 DOM 降级。 */ export interface SSRData { item: { title: string; itemId: string; images: string[]; videos?: Array<{ url: string; videoThumbnailURL?: string }>; }; skuBase?: { props: Array<{ pid: string; name: string; // "颜色分类" / "商品规格" values: Array<{ vid: string; name: string; // SKU 规格名 image?: string; // SKU 图片 }>; }>; }; params?: { basicParamList?: Array<{ propertyName: string; valueName: string }>; enhanceParamList?: Array<{ propertyName: string; valueName: string }>; }; price?: { priceText?: string; priceMoney?: string; }; } /** * 尝试从页面提取 SSR 数据(淘宝/天猫 __ICE_APP_CONTEXT__) */ export function extractSSRData(): SSRData | null { try { const ctx = (window as any).__ICE_APP_CONTEXT__; if (!ctx?.loaderData?.home?.data?.res) return null; const res = ctx.loaderData.home.data.res; // 基础结构验证 if (!res.item?.title || !res.item?.itemId) return null; // 提取参数(两个来源都试) const industryParams = res.plusViewVO?.industryParamVO; const extensionParams = res.componentsVO?.extensionInfoVO?.infos?.find( (i: any) => i.type === 'BASE_PROPS' ); return { item: { title: res.item.title, itemId: res.item.itemId, images: res.item.images || [], videos: res.item.videos }, skuBase: res.skuBase, params: { basicParamList: industryParams?.basicParamList || extensionParams?.items || [], enhanceParamList: industryParams?.enhanceParamList || [] }, price: res.componentsVO?.priceVO?.price || res.componentsVO?.priceVO?.extraPrice }; } catch (err) { console.warn('[SSR] 提取失败:', err); return null; } }