// 目标:把解析出的图片数组转成“逗号+空格”分隔的字符串,
// 并且把它写回到 parsedObject 的图片字段(images / 图片 / image),不保留数组。
function extractBalancedJSON(str) {
const s = String(str || '');
const startIdx = s.search(/[\{\[]/);
if (startIdx === -1) return null;
const openChar = s[startIdx];
const closeChar = openChar === '{' ? '}' : ']';
for (let i = startIdx; i < s.length; i++) {
if (s[i] === openChar) depth++;
else if (s[i] === closeChar) depth--;
if (depth === 0) return s.slice(startIdx, i + 1);
return s.slice(startIdx);
function buildImagesCommaStringFromObj(obj) {
if (obj.图片) imgs = Array.isArray(obj.图片) ? obj.图片.slice() : [obj.图片];
else if (obj.images) imgs = Array.isArray(obj.images) ? obj.images.slice() : [obj.images];
else if (obj.image) imgs = Array.isArray(obj.image) ? obj.image.slice() : [obj.image];
imgs = imgs.map(u => (u || '').toString().trim()).filter(Boolean);
imgs = imgs.map(u => u.replace(/[\r\n]+/g, ' '));
for (const item of items) {
let raw = item.json.output || (item.json.response && item.json.response[0] && item.json.response[0].text) || item.json.text || '';
raw = String(raw || '').trim();
raw = raw.replace(/```(?:json)?\r?\n?/i, '').replace(/```/g, '').trim();
raw = raw.replace(/^json\s*[:\-\n\r]*/i, '').trim();
if (/^".*"$/.test(raw) || (/^'.*'$/.test(raw) && raw.includes('\\"'))) {
let candidate = extractBalancedJSON(raw) || raw;
const tryParse = s => { try { return JSON.parse(s); } catch (e) { return null; } };
parsed = tryParse(candidate);
let s = candidate.replace(/\\r?\\n/g, '\\n');
const one = tryParse(s);
if (one && typeof one === 'string') parsed = tryParse(one);
let s2 = candidate.replace(/\\"/g, '"').replace(/\\n/g, '\n');
if (!parsed) parsed = { rawText: candidate };
const normalizeAndPush = (obj) => {
const imagesString = buildImagesCommaStringFromObj(obj);
// **强制把图片字段替换为字符串**(覆盖原数组)
try { obj.images = imagesString; } catch(e) {}
try { obj.图片 = imagesString; } catch(e) {}
try { obj.image = imagesString; } catch(e) {}
const title = obj.标题 || obj.title || obj.displayTitle || '';
const text = obj.正文 || obj.text || obj.summary || '';
const like = obj.点赞数 || obj.likeCount || obj.likes || '';
const fav = obj.收藏数 || obj.collectCount || obj.favorites || '';
const comments = obj.评论数 || obj.commentCount || obj.comments || '';
const shares = obj.分享数 || obj.shareCount || obj.shares || '';
const url = obj.url || obj.link || obj.noteUrl || '';
// 把 imagesString 写在 parsedObject 并且 row 的第二列
imagesString: imagesString,
row: [title, imagesString, text, like, fav, comments, shares, url]
if (Array.isArray(parsed)) {
for (const obj of parsed) {
} else if (parsed && typeof parsed === 'object') {
if (Array.isArray(parsed.notes)) {
for (const obj of parsed.notes) normalizeAndPush(obj);
} else if (Array.isArray(parsed.items)) {
for (const obj of parsed.items) normalizeAndPush(obj);
normalizeAndPush(parsed);
rows.push({ json: { parsedObject: parsed, row: [String(candidate).slice(0, 100)] } });
if (rows.length === 0) rows.push({ json: { parsedObject: parsed, row: [String(candidate).slice(0,200)] } });
for (const r of rows) results.push(r);