/** * 用真实保存的 Ozon 页面验证采集逻辑(不依赖浏览器) * 用法:先 esbuild 打包再 node 运行(见 README / 命令注释) */ import { readFileSync } from 'node:fs'; import { join } from 'node:path'; import { extractOzonState } from '../src/collector/ozon-state'; import { extractJsonLd } from '../src/collector/jsonld'; import { toOriginalUrl, toThumbUrl, pickBestFromSrcset } from '../src/collector/url'; class FakeEl { id: string; attrs: Record; constructor(id: string, attrs: Record) { this.id = id; this.attrs = attrs; } getAttribute(name: string): string | null { return this.attrs[name] ?? null; } get textContent(): string { return this.attrs['text'] ?? ''; } } function buildFakeDoc(html: string) { const stateEls: FakeEl[] = []; const re = //gs; let m: RegExpExecArray | null; while ((m = re.exec(html))) { stateEls.push(new FakeEl('state-' + m[1], { 'data-state': m[2] })); } const ldEls: FakeEl[] = []; const re2 = /]*type="application\/ld\+json"[^>]*>(.*?)<\/script>/gs; while ((m = re2.exec(html))) { ldEls.push(new FakeEl('', { text: m[1] })); } return { querySelectorAll(sel: string): FakeEl[] { if (sel === 'div[id^="state-"]') return stateEls; if (sel === 'script[type="application/ld+json"]') return ldEls; return []; }, }; } function check(name: string, actual: unknown, expected: unknown): void { const a = JSON.stringify(actual); const e = JSON.stringify(expected); const ok = a === e; console.log(`${ok ? '✅' : '❌'} ${name}`); if (!ok) { console.log(' expected:', e); console.log(' actual :', a); } } for (const fn of ['../reference/ozon1.html', '../reference/ozon2.html']) { console.log(`\n========== ${fn} ==========`); const html = readFileSync(join(process.cwd(), fn), 'utf8'); (globalThis as any).document = buildFakeDoc(html); const state = extractOzonState(); console.log('state:', JSON.stringify({ title: state.title, price: state.price, originalPrice: state.originalPrice, rating: state.rating, reviewCount: state.reviewCount, gallery: state.galleryImages.length, videos: state.videos, variants: state.skuVariants, characteristics: state.characteristics, }, null, 1)); const ld = extractJsonLd(); console.log('jsonld:', JSON.stringify(ld)); } // ── URL 工具验证 ── console.log('\n========== url tools =========='); const rules = [ { match: /\/wc\d+\//, replace: '/' }, { match: /\/c\d+\//, replace: '/' }, { match: /(?