变更跟踪 变更跟踪可用于随时间监控并检测网页内容的变化。该功能在 JavaScript 和 Python SDK 中均可用。

概览

变更跟踪使你能够:
  • 检测网页自上次抓取以来是否发生变化
  • 查看不同抓取之间的具体更改
  • 获取关于变更内容的结构化数据
  • 控制变更的可见性
使用 changeTracking 格式,你可以监控网站上的变化,并获取以下信息:
  • previousScrapeAt:当前页面所对比的上一次抓取的时间戳(如果没有之前的抓取则为 null
  • changeStatus:两个页面版本比较的结果
    • new:此页面之前不存在或未被发现(通常 previousScrapeAtnull
    • same:自上次抓取以来,此页面的内容未发生变化
    • changed:自上次抓取以来,此页面的内容已发生变化
    • removed:自上次抓取以来,此页面已被移除
  • visibility:当前页面/URL 的可见性
    • visible:此页面可见,表示其 URL 是通过自然路径(经由其他可见页面的链接或 sitemap)被发现的
    • hidden:此页面不可见,表示它仍可在网上访问,但不再能通过 sitemap 或站点爬取被发现。我们只能在该链接曾在先前的爬取或抓取中可见并被捕获的情况下识别此类不可见链接

SDK

基本用法

要启用变更跟踪,在抓取某个 URL 时在 formats 中加入 'changeTracking'
const firecrawl = new Firecrawl({ apiKey: 'your-api-key' });
const result = await firecrawl.scrape('https://example.com', {
  formats: ['markdown', 'changeTracking']
});

// 访问变更跟踪数据
console.log(result.changeTracking)
示例响应:
{
  "url": "https://firecrawl.dev",
  "markdown": "# 打造卓越客户体验的 AI 代理\n\n让用户爱不释手的聊天机器人……",
  "changeTracking": {
    "previousScrapeAt": "2025-04-10T12:00:00Z",
    "changeStatus": "changed",
    "visibility": "visible"
  }
}

高级选项

你可以在 formats 数组中传入一个对象来配置 changeTracking:
const result = await firecrawl.scrape('https://example.com', {
  formats: [
    'markdown',
    {
      type: 'changeTracking',
      modes: ['git-diff', 'json'], // 启用指定的变更跟踪模式
      schema: {
        type: 'object',
        properties: {
          title: { type: 'string' },
          content: { type: 'string' }
        }
      }, // 用于结构化 JSON 比对的模式
      prompt: 'Custom prompt for extraction', // 可选的自定义提示
      tag: 'production' // 可选标签,用于区分各自的变更跟踪历史
    }
  ]
});

// 访问 git-diff 格式的变更
if (result.changeTracking.diff) {
  console.log(result.changeTracking.diff.text); // Git 风格的 diff 文本
  console.log(result.changeTracking.diff.json); // 结构化的 diff 数据
}

// 访问 JSON 比对的变更
if (result.changeTracking.json) {
  console.log(result.changeTracking.json.title.previous); // 先前标题
  console.log(result.changeTracking.json.title.current); // 当前标题
}

Git Diff 结果示例:

 **2025 年 4 月 13 日**
 
-**下午 05:55:05**
+**下午 05:58:57**

...

JSON 对比结果示例:

{
  "time": { 
    "previous": "2025-04-13T17:54:32Z", 
    "current": "2025-04-13T17:55:05Z" 
  }
}

数据模型

changeTracking 功能包含以下数据模型:
interface FirecrawlDocument {
  // ... other properties
  changeTracking?: {
    previousScrapeAt: string | null;
    changeStatus: "new" | "same" | "changed" | "removed";
    visibility: "visible" | "hidden";
    diff?: {
      text: string;
      json: {
        files: Array<{
          from: string | null;
          to: string | null;
          chunks: Array<{
            content: string;
            changes: Array<{
              type: string;
              normal?: boolean;
              ln?: number;
              ln1?: number;
              ln2?: number;
              content: string;
            }>;
          }>;
        }>;
      };
    };
    json?: any;
  };
}

interface ChangeTrackingFormat {
  type: 'changeTracking';
  prompt?: string;
  schema?: any;
  modes?: ("json" | "git-diff")[];
  tag?: string | null;
}

interface ScrapeParams {
  // ... other properties
  formats?: Array<'markdown' | 'html' | ChangeTrackingFormat>;
}

变更跟踪模式

变更跟踪功能支持两种模式:

Git-Diff 模式

git-diff 模式提供一种与 Git 输出相似的传统 diff 格式。它逐行展示变更,并用新增与删除标记。 示例输出:
@@ -1,1 +1,1 @@
-旧版本
+新版本
差异的结构化 JSON 表示包括:
  • files:已更改文件的数组(在网页场景中通常只有一个)
  • chunks:文件内的变更片段
  • changes:按类型(add、delete、normal)标注的单行变更

JSON 模式

json 模式会对从内容中提取的特定字段进行结构化对比。这有助于追踪具体数据点的变化,而不是比较整段内容。 示例输出:
{
  "title": {
    "previous": "旧标题",
    "current": "新标题"
  },
  "price": {
    "previous": "US$19.99",
    "current": "US$24.99"
  }
}
要使用 JSON 模式,你需要提供一个 schema,用于定义要提取和对比的字段。

重要说明

以下是在使用 changeTracking 功能时需要了解的一些关键细节:
  • 比较方式:抓取结果始终通过其 markdown 响应进行比较。
    • 使用 changeTracking format 时,必须同时指定 markdown format。也可以额外指定其他 formats。
    • 比较算法对空白字符和内容顺序的变化具备鲁棒性。为抵御带有随机化 URL 的验证码和反爬措施,目前会忽略 iframe 的源 URL。
  • 匹配历史抓取:用于比较的历史抓取目前基于源 URL、团队 ID、markdown format 和 tag 参数进行匹配。
    • 为获得有效比较,输入的 URL 应与此前针对相同内容的请求完全一致。
    • 使用不同的 includePaths/excludePaths 爬取相同 URL,在使用 changeTracking 时会产生不一致。
    • 使用不同的 includeTags/excludeTags/onlyMainContent 抓取相同 URL,在使用 changeTracking 时会产生不一致。
    • 被比较的页面也会与仅包含 markdown format 而不包含 changeTracking format 的历史抓取进行比对。
    • 比较限定在你的团队范围内。如果你首次使用你的 API key 抓取某个 URL,其 changeStatus 将始终为 new,即使其他 Firecrawl 用户之前已抓取过它。
  • Beta 状态:在 Beta 期间,建议关注结果文档中的 warning 字段,并处理响应中可能缺失的 changeTracking 对象。
    • 当用于查找比对对象的数据库查询超时时,可能会出现这种情况。

示例

基础抓取示例

// 请求
{
    "url": "https://firecrawl.dev",
    "formats": ["markdown", "changeTracking"]
}

// 响应
{
  "success": true,
  "data": {
    "markdown": "...",
    "metadata": {...},
    "changeTracking": {
      "previousScrapeAt": "2025-03-30T15:07:17.543071+00:00",
      "changeStatus": "same",
      "visibility": "visible"
    }
  }
}

爬网示例

// 请求
{
    "url": "https://firecrawl.dev",
    "scrapeOptions": {
        "formats": ["markdown", "changeTracking"]
    }
}

跟踪商品价格变动

const result = await firecrawl.scrape('https://example.com/product', {
  formats: [
    'markdown',
    {
      type: 'changeTracking',
      modes: ['json'],
      schema: {
        type: 'object',
        properties: {
          price: { type: 'string' },
          availability: { type: 'string' }
        }
      }
    }
  ]
});

if (result.changeTracking.changeStatus === 'changed') {
  console.log(`价格已从 ${result.changeTracking.json.price.previous} 变为 ${result.changeTracking.json.price.current}`);
}

使用 Git-Diff 监控内容更改

const result = await firecrawl.scrape('https://example.com/blog', {
  formats: [
    'markdown',
    { type: 'changeTracking', modes: ['git-diff'] }
  ]
});

if (result.changeTracking.changeStatus === 'changed') {
  console.log('内容发生了更改:');
  console.log(result.changeTracking.diff.text);
}

计费

changeTracking 功能目前处于测试阶段。使用基础的 changeTracking 功能和 git-diff 模式不收取额外费用。但如果你使用用于结构化数据比对的 json 模式,页面抓取将按每页收取 5 个积分。