You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
57 lines
2.4 KiB
57 lines
2.4 KiB
|
7 days ago
|
// 解析 data.js(lanhu_Axure_Mapping_Data)提取页面全部文本
|
||
|
|
import fs from 'node:fs';
|
||
|
|
|
||
|
|
const raw = fs.readFileSync('e:/code/crm-backend-matt/.scratch/lanhu-latest/team-page-data.js', 'utf8');
|
||
|
|
console.log('file len:', raw.length);
|
||
|
|
|
||
|
|
// data.js 形如:$axure.loadCurrentPage(lanhu_Axure_Mapping_Data({...}))
|
||
|
|
// 用括号配对截取 JSON 主体
|
||
|
|
const start = raw.indexOf('{');
|
||
|
|
let depth = 0, end = -1, inStr = false, esc = false;
|
||
|
|
for (let i = start; i < raw.length; i++) {
|
||
|
|
const c = raw[i];
|
||
|
|
if (esc) { esc = false; continue; }
|
||
|
|
if (c === '\\') { esc = true; continue; }
|
||
|
|
if (c === '"') inStr = !inStr;
|
||
|
|
if (inStr) continue;
|
||
|
|
if (c === '{') depth++;
|
||
|
|
else if (c === '}') { depth--; if (depth === 0) { end = i; break; } }
|
||
|
|
}
|
||
|
|
if (end < 0) { console.log('brace match failed'); process.exit(1); }
|
||
|
|
const data = JSON.parse(raw.slice(start, end + 1));
|
||
|
|
console.log('top keys:', Object.keys(data).join(','));
|
||
|
|
console.log('url:', data.url, '| generationDate:', data.generationDate);
|
||
|
|
|
||
|
|
// 递归提取所有字符串字段的文本(type/scriptId/script 等技术字段除外)
|
||
|
|
const TECH = new Set(['type', 'scriptId', 'script', 'id', 'scriptId', 'style', 'adaptivePlan', 'packageId', 'parentId', 'fillType', 'fontWeight', 'location', 'size', 'limbo', 'hidden', 'locked', 'generationDate', 'defaultAdaptiveView', 'url', 'packageIdHash', 'annotations', 'map', 'propagation']);
|
||
|
|
const texts = [];
|
||
|
|
function walk(obj, path) {
|
||
|
|
if (obj === null || obj === undefined) return;
|
||
|
|
if (typeof obj === 'string') {
|
||
|
|
const t = obj.trim();
|
||
|
|
if (t && !/^[\d\s.,:;()\-/]+$/.test(t)) texts.push({ path, text: t });
|
||
|
|
} else if (Array.isArray(obj)) {
|
||
|
|
obj.forEach((v, i) => walk(v, `${path}[${i}]`));
|
||
|
|
} else if (typeof obj === 'object') {
|
||
|
|
for (const [k, v] of Object.entries(obj)) {
|
||
|
|
if (k === 'text' || k === 'richText' || k === 'name' || k === 'label' || k === 'html') {
|
||
|
|
walk(v, `${path}.${k}`);
|
||
|
|
} else if (!TECH.has(k)) {
|
||
|
|
walk(v, `${path}.${k}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
walk(data, '$');
|
||
|
|
console.log('text fragments:', texts.length);
|
||
|
|
console.log('--- first 80 fragments ---');
|
||
|
|
const seen = new Set();
|
||
|
|
let shown = 0;
|
||
|
|
for (const t of texts) {
|
||
|
|
const clean = t.text.replace(/<[^>]+>/g, ' ').replace(/ /g, ' ').replace(/\s+/g, ' ').trim();
|
||
|
|
if (!clean || seen.has(clean)) continue;
|
||
|
|
seen.add(clean);
|
||
|
|
console.log(' ', clean.slice(0, 120));
|
||
|
|
if (++shown >= 80) break;
|
||
|
|
}
|