crawl4ai真实数据结构raw_markdown 的正确路径是:

item.json.results[0].markdown_v2.raw_markdown

我们来分解一下这个正确的路径:

  1. item:这是 n8n 传给 Code 节点的单个数据项,它的顶层就有一个叫 "json" 的对象。

  2. .json:进入这个 "json" 对象。

  3. .results:在 "json" 对象内部,找到 "results" 字段,它是一个数组 [ ... ]

  4. [0]:从这个数组中,取出第一个元素(因为编号从0开始)。

  5. .markdown_v2:在这个元素对象中,找到 "markdown_v2" 字段。

  6. .raw_markdown:最后,从 "markdown_v2" 对象中,取出我们最终需要的 "raw_markdown" 文本。

你之前的尝试都非常接近,只是因为 crawl4ai 的输出实际上被包裹在了另一层 json 对象里,这是我们之前无法预料到的。你通过 console.log 把它找了出来,这正是最专业的调试方法!


最终的 n8n Code 节点代码

现在,请将你的 Code 节点代码完整替换为下面这个最终正确版本。它使用了正确的路径,并且依然保持了“健壮性”,可以防止因为未来可能的抓取失败而导致工作流崩溃。

JavaScript

// 获取上一个节点传入的所有数据项
const items = $input.all();

// 遍历每一个数据项进行处理
for (const item of items) {
  
  // 使用我们最终确定的正确路径来安全地访问数据
  let text = item.json?.results?.[0]?.markdown_v2?.raw_markdown;

  if (text) {
    
    // --- 最终清理流程 ---

    // 1. 【关键新增步骤】将字符串 "\\n" 替换为真正的换行符 \n
    // 这是解决你看到 `\n` 而不换行的核心
    text = text.replaceAll('\\n', '\n');

    // 2. 定义一个更全面的“垃圾内容”关键词黑名单
    const junkKeywords = [
      '分类', '图像来源', '图像加注文字', '补充报导:BBC国际部',
      'Article Information', 'Author,', 'Role,', '热读', 'End of 热读',
      '更多相关内容', '热门内容', '特别推荐', 'BBC值得信赖的原因', '© 2025 BBC'
    ];

    // 3. 先用更强的正则表达式,移除所有图片和链接的 Markdown 标记
    text = text.replace(/(!?\[[\s\S]*?\]\([\s\S]*?\))+/g, '');

    // 4. 【核心改进】按行处理,用更严格的规则过滤
    const lines = text.split('\n');
    const cleanedLines = lines
      .map(line => line.trim()) // 去除每行首尾的空格
      .filter(line => {
        // 规则a: 过滤掉空行
        if (line.length === 0) return false;
        
        // 规则b: 过滤掉无意义的符号行
        if (line === '*' || line === '###') return false;
        
        // 规则c: 过滤掉类似 "1. 1"  "10. 10" 这样的错误行
        if (/^\d+\.\s\d+$/.test(line)) return false;

        // 规则d: 过滤掉看起来像单独日期的行
        if (/^\d{4}\d{1,2}\d{1,2}$/.test(line) || /^\d+\s小时前$/.test(line)) return false;
        
        // 规则e: 如果行内包含任何一个黑名单关键词,就过滤掉它
        if (junkKeywords.some(keyword => line.includes(keyword))) return false;
        
        return true; // 保留所有“干净”的行
      });
    
    // 5. 将干净的行重新组合,并整理段落格式
    let cleanedText = cleanedLines.join('\n');
    cleanedText = cleanedText.replace(/\n{3,}/g, '\n\n');

    // --- 清理流程结束 ---

    item.json.cleaned_markdown = cleanedText.trim();

  } else {
    item.json.cleaned_markdown = "处理失败:未能在指定的路径中找到内容。";
  }
}

// 返回被修改后的数据项
return items;