Obscura 请求拦截——阻断 API、Mock 响应、注入脚本

Obscura 三种请求拦截方式:CDP Fetch.enable、Rust Library Interception API、内置 Stealth Tracker Blocklist。实战屏蔽广告、Mock 接口、注入 Preload Script。

亿牛云技术团队2026年7月7日3 分钟阅读

控制页面的每一个请求

网页加载时会发起大量网络请求——HTML、CSS、JS、图片、分析脚本、API 调用。在爬虫和自动化场景中,你通常不需要全部加载它们。Obscura 提供了三种层次的请求拦截机制:

  1. CDP Fetch.enable:从 Puppeteer/Playwright 侧拦截
  2. Rust Library Interception API:从 Rust 代码侧拦截
  3. 内置 Stealth Tracker Blocklist:网络层自动拦截

方式一:CDP Fetch.enable(Puppeteer/Playwright)

这是最常用的方式,适合已有 Puppeteer 或 Playwright 脚本的用户。

按资源类型屏蔽

// Puppeteer
await page.setRequestInterception(true);
 
page.on('request', req => {
  if (['image', 'media', 'font'].includes(req.resourceType())) {
    req.abort();
  } else {
    req.continue();
  }
});
// Playwright
await page.route('**/*', route => {
  if (['image', 'media', 'font'].includes(route.request().resourceType())) {
    route.abort();
  } else {
    route.continue();
  }
});

屏蔽图片和字体可以大幅减少页面加载时间和带宽消耗,对于以文本内容为主的爬虫场景特别有效。

按 URL 模式屏蔽

// Puppeteer
page.on('request', req => {
  const url = req.url();
  if (url.includes('google-analytics.com') || url.includes('doubleclick.net')) {
    req.abort();
  } else {
    req.continue();
  }
});
// Playwright:支持正则
await page.route(/google-analytics\.com|doubleclick\.net/, route => route.abort());

伪造 API 响应

在爬虫中经常需要模拟真实的 API 响应来绕过前端校验或加速测试:

// Puppeteer
page.on('request', req => {
  if (req.url().endsWith('/api/feature-flags')) {
    req.respond({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({ newDashboard: true }),
    });
  } else {
    req.continue();
  }
});
// Playwright
await page.route('**/api/feature-flags', route => {
  route.fulfill({
    status: 200,
    contentType: 'application/json',
    body: JSON.stringify({ newDashboard: true }),
  });
});

修改请求 Headers

// Puppeteer
page.on('request', req => {
  req.continue({
    headers: { ...req.headers(), 'X-Custom-Header': 'value' },
  });
});

生产级屏蔽列表

const BLOCK_DOMAINS = [
  'google-analytics.com',
  'googletagmanager.com',
  'doubleclick.net',
  'facebook.net',
  'segment.io',
  'mixpanel.com',
  'hotjar.com',
  'criteo.com',
];
 
page.on('request', req => {
  if (BLOCK_DOMAINS.some(domain => req.url().includes(domain))) {
    req.abort();
  } else {
    req.continue();
  }
});

方式二:Stealth 内置 Tracker Blocklist

如果你不想手动配置屏蔽规则,Stealth 模式内置了 Peter Lowe 的广告与跟踪器域名列表,覆盖 3500+ 域名:

obscura fetch https://example.com --stealth
obscura serve --stealth

启用 Stealth 后,以下类型的请求在网络层就被阻止,不会进入 V8 和 DOM:

  • 分析统计:Google Analytics、Mixpanel、Hotjar
  • 广告网络:DoubleClick、Criteo、Adnxs
  • 社交追踪:Facebook.net
  • 指纹采集脚本

拦截发生在 obscura-net 层,请求在离开发送前被检查。支持子域名通配匹配。

方式三:Rust Library Interception API

如果你将 Obscura 作为 Rust 库嵌入自有项目,可以使用更底层的拦截 API。

enable_interception 通道

enable_interception() 返回一个 Receiver 通道,收到每个 JS fetch()/XHR 请求。通过 resolver 决定如何处理:

use obscura::{Browser, InterceptResolution};
 
let mut page = browser.new_page().await?;
let mut rx = page.enable_interception();
 
// 在独立任务中处理拦截
tokio::spawn(async move {
    while let Some(req) = rx.recv().await {
        let action = if req.url.contains("/ads") {
            InterceptResolution::Fail { reason: "blocked".into() }
        } else if req.url.ends_with("/api/flags") {
            InterceptResolution::Fulfill {
                status: 200,
                headers: Default::default(),
                body: r#"{"newDashboard":true}"#.into(),
            }
        } else {
            InterceptResolution::Continue {
                url: None,
                method: None,
                headers: None,
                body: None,
            }
        };
        let _ = req.resolver.send(action);
    }
});
 
page.goto("https://example.com").await?;
page.settle(2000).await;

三种 Resolution:

Resolution含义
Continue放行,可选修改 url/method/headers/body
Fulfill直接返回伪造响应
Fail阻止请求并返回错误原因

Continue 中的 url: Some(...) 可以重写请求目标。新的 URL 会重新通过 SSRF 校验。

Preload Script

在页面加载之前注入 JavaScript,执行时机早于页面自身的 <script> 标签:

page.add_preload_script("window.__patched = true;");
page.goto("https://example.com").await?;

可用于:

  • 覆盖全局函数
  • 注入监控探针
  • 修改 Math.randomDate.now 使页面行为可预测
  • 设置 window.__obscura = true 标记

on_request / on_response 被动回调

如果不需要拦截,只需要观察,使用被动回调:

page.on_request(Arc::new(|info| {
    println!("Request: {} {}", info.method, info.url);
}));
 
page.on_response(Arc::new(|info, resp| {
    if info.resource_type == ResourceType::Fetch {
        println!("API response: {} -> {} bytes", info.url, resp.body.len());
    }
}));

on_response 是捕获 SPA 异步加载的 JSON 数据的主要方式。

三层拦截对比

方式层面适用场景是否需要代码
CDP Fetch.enableCDP 协议已有 Puppeteer/Playwright 脚本JavaScript
Stealth Blocklist网络层快速启用,零配置
Rust Library APIRust 库嵌入项目深度集成Rust

三层可以组合使用:Stealth Blocklist 拦截通用 Tracker,CDP 拦截处理业务规则,Rust API 处理程序内部逻辑。

安全注意

Continue 中的 URL 重写会重新通过 SSRF 校验(validate_fetch_url),防止通过请求拦截绕过 --allow-private-network 限制。

总结

Obscura 提供了从网络层到 CDP 层到 Rust 层的完整请求控制能力。日常使用中,Stealth 模式的内置 Blocklist 可以解决大部分 Tracker 拦截需求;需要精细控制时,CDP 拦截和 Rust Library API 提供了完全的灵活性。

需要企业代理方案?

我们可根据目标站点、并发规模与稳定性目标提供定制方案。