/**
* 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;
}
}