🥳加入无抓取社区领取您的免费试用,访问我们强大的网页抓取工具包!
返回博客

如何最大化优化您的浏览器流量使用?

Alex Johnson
Alex Johnson

Senior Web Scraping Engineer

26-Apr-2025

概述

在使用 Puppeteer 进行数据抓取时,流量消耗是一个重要考虑因素。特别是在使用代理服务时,流量成本可能会显著增加。为了优化流量使用,我们可以采用以下策略:

  1. 资源拦截:通过拦截不必要的资源请求来减少流量消耗。
  2. 请求 URL 拦截:根据 URL 特征进一步拦截特定请求,以减少流量。
  3. 模拟移动设备:使用移动设备配置获取较轻的页面版本。
  4. 综合优化:结合上述方法以实现最佳效果。

优化方案 1:资源拦截

资源拦截简介

在 Puppeteer 中,page.setRequestInterception(true) 可以捕获浏览器发起的每个网络请求,并决定 继续 (request.continue())、终止 (request.abort()) 或 自定义响应 (request.respond())。

这种方法可以显著减少带宽消耗,特别适合用于 爬取截屏性能优化 这类场景。

可拦截的资源类型及建议

资源类型 描述 示例 拦截后的影响 推荐
image 图片资源 JPG/PNG/GIF/WebP 图片 图片将不会显示 ⭐ 安全
font 字体文件 TTF/WOFF/WOFF2 字体 将使用系统默认字体 ⭐ 安全
media 媒体文件 视频/音频文件 媒体内容无法播放 ⭐ 安全
manifest Web 应用清单 PWA 配置文件 可能影响 PWA 功能 ⭐ 安全
prefetch 预取资源 <link rel="prefetch"> 对页面影响极小 ⭐ 安全
stylesheet CSS 样式表 外部 CSS 文件 页面样式丢失,可能影响布局 ⚠️ 注意
websocket WebSocket 实时通信连接 实时功能禁用 ⚠️ 注意
eventsource 服务器发送事件 服务器推送数据 推送功能禁用 ⚠️ 注意
preflight CORS 预检请求 OPTIONS 请求 跨域请求失败 ⚠️ 注意
script JavaScript 脚本 外部 JS 文件 动态功能禁用,SPA 可能无法正常渲染 ❌ 避免
xhr XHR 请求 AJAX 数据请求 无法获取动态数据 ❌ 避免
fetch Fetch 请求 现代 AJAX 请求 无法获取动态数据 ❌ 避免
document 主文档 HTML 页面本身 页面无法加载 ❌ 避免

推荐级别说明:

  • 安全:拦截几乎对数据抓取或首屏渲染没有影响,建议默认阻止。
  • ⚠️ 注意:可能破坏样式、实时功能或跨域请求;需根据业务判断。
  • 避免:高概率导致 SPA/动态网站无法正常渲染或获取数据,除非你绝对确定不需要这些资源。

资源拦截示例代码

javascript Copy
import puppeteer from 'puppeteer-core';

const scrapelessUrl = 'wss://browser.scrapeless.com/browser?token=your_api_key&session_ttl=180&proxy_country=ANY';

async function scrapeWithResourceBlocking(url) {
    const browser = await puppeteer.connect({
        browserWSEndpoint: scrapelessUrl,
        defaultViewport: null
    });
    const page = await browser.newPage();

    // 启用请求拦截
    await page.setRequestInterception(true);

    // 定义要拦截的资源类型
    const BLOCKED_TYPES = new Set([
        'image',
        'font',
        'media',
        'stylesheet',
    ]);

    // 拦截请求
    page.on('request', (request) => {
        if (BLOCKED_TYPES.has(request.resourceType())) {
            request.abort();
            console.log(`已拦截:${request.resourceType()} - ${request.url().substring(0, 50)}...`);
        } else {
            request.continue();
        }
    });

    await page.goto(url, {waitUntil: 'domcontentloaded'});

    // 提取数据
    const data = await page.evaluate(() => {
        return {
            title: document.title,
            content: document.body.innerText.substring(0, 1000)
        };
    });

    await browser.close();
    return data;
}

// 使用示例
scrapeWithResourceBlocking('https://www.scrapeless.com')

.then(data => console.log('抓取结果:', data))
.catch(error => console.error('抓取失败:', error));

Copy
## 优化方案二:请求URL拦截

除了按资源类型进行拦截外,还可以根据URL特征进行更细粒度的拦截控制。这对于阻止广告、分析脚本和其他不必要的第三方请求特别有效。

### URL拦截策略

1. **按域名拦截**:阻止来自特定域名的所有请求
2. **按路径拦截**:阻止来自特定路径的请求
3. **按文件类型拦截**:阻止具有特定扩展名的文件
4. **按关键字拦截**:阻止URL中包含特定关键字的请求

### 常见可拦截的URL模式

| URL模式 | 描述 | 示例 | 推荐 |
|--------|-----------|------------------------------------------------|-------|
| 广告服务 | 广告网络域名 | `ad.doubleclick.net`, `googleadservices.com` | ⭐ 安全 |
| 分析服务 | 统计和分析脚本 | `google-analytics.com`, `hotjar.com` | ⭐ 安全 |
| 社交媒体插件 | 社交分享按钮等 | `platform.twitter.com`, `connect.facebook.net` | ⭐ 安全 |
| 跟踪像素 | 跟踪用户行为的像素 | 包含`pixel`、`beacon`、`tracker`的URL | ⭐ 安全 |
| 大媒体文件 | 大型视频、音频文件 | `.mp4`、`.webm`、`.mp3`等扩展名 | ⭐ 安全 |
| 字体服务 | 在线字体服务 | `fonts.googleapis.com`, `use.typekit.net` | ⭐ 安全 |
| CDN资源 | 静态资源CDN | `cdn.jsdelivr.net`, `unpkg.com` | ⚠️ 注意 |

### URL拦截示例代码

```javascript
import puppeteer from 'puppeteer-core';

const scrapelessUrl = 'wss://browser.scrapeless.com/browser?token=your_api_key&session_ttl=180&proxy_country=ANY';

async function scrapeWithUrlBlocking(url) {
    const browser = await puppeteer.connect({
        browserWSEndpoint: scrapelessUrl,
        defaultViewport: null
    });
    const page = await browser.newPage();

    // 启用请求拦截
    await page.setRequestInterception(true);

    // 定义要拦截的域名和URL模式
    const BLOCKED_DOMAINS = [
        'google-analytics.com',
        'googletagmanager.com',
        'doubleclick.net',
        'facebook.net',
        'twitter.com',
        'linkedin.com',
        'adservice.google.com',
    ];

    const BLOCKED_PATHS = [
        '/ads/',
        '/analytics/',
        '/pixel/',
        '/tracking/',
        '/stats/',
    ];

    // 拦截请求
    page.on('request', (request) => {
        const url = request.url();

        // 检查域名
        if (BLOCKED_DOMAINS.some(domain => url.includes(domain))) {
            request.abort();
            console.log(`拦截的域名: ${url.substring(0, 50)}...`);
            return;
        }

        // 检查路径
        if (BLOCKED_PATHS.some(path => url.includes(path))) {
            request.abort();
            console.log(`拦截的路径: ${url.substring(0, 50)}...`);
            return;
        }

        // 允许其他请求
        request.continue();
    });

    await page.goto(url, {waitUntil: 'domcontentloaded'});

    // 提取数据
    const data = await page.evaluate(() => {
        return {
            title: document.title,
            content: document.body.innerText.substring(0, 1000)
        };
    });

    await browser.close();
    return data;
}

// 用法
scrapeWithUrlBlocking('https://www.scrapeless.com')
    .then(data => console.log('抓取结果:', data))
    .catch(error => console.error('抓取失败:', error));

优化方案三:模拟移动设备

模拟移动设备是另一种有效的流量优化策略,因为移动网站通常提供更轻量的页面内容。

移动设备模拟的优势

  1. 更轻量的页面版本:许多网站为移动设备提供更简洁的内容
  2. 较小的图像资源:移动版本通常加载较小的图像
  3. 简化的CSS和JavaScript:移动版本通常使用简化的样式和脚本
  4. 减少广告和非核心内容:移动版本通常会去掉一些非核心功能
  5. 自适应响应:获取针对小屏幕优化的内容布局

移动设备模拟配置

以下是几种常用移动设备的配置参数:

javascript Copy
const iPhoneX = {
    viewport: {
        width: 375,
        height: 812,
        deviceScaleFactor: 3,
        isMobile: true,
        hasTouch: true,
        isLandscape: false
    }
};

或者直接使用puppeteer的内置方法来模拟移动设备

javascript Copy
import { KnownDevices } from 'puppeteer-core';
const iPhone = KnownDevices['iPhone 15 Pro'];
```javascript
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.emulate(iPhone);

移动设备模拟示例代码

javascript Copy
import puppeteer, {KnownDevices} from 'puppeteer-core';

const scrapelessUrl = 'wss://browser.scrapeless.com/browser?token=your_api_key&session_ttl=180&proxy_country=ANY';

async function scrapeWithMobileEmulation(url) {
    const browser = await puppeteer.connect({
        browserWSEndpoint: scrapelessUrl,
        defaultViewport: null
    });

    const page = await browser.newPage();

    // 设置移动设备模拟
    const iPhone = KnownDevices['iPhone 15 Pro'];
    await page.emulate(iPhone);

    await page.goto(url, {waitUntil: 'domcontentloaded'});
    // 提取数据
    const data = await page.evaluate(() => {
        return {
            title: document.title,
            content: document.body.innerText.substring(0, 1000)
        };
    });

    await browser.close();
    return data;
}

// 用法
scrapeWithMobileEmulation('https://www.scrapeless.com')
    .then(data => console.log('抓取结果:', data))
    .catch(error => console.error('抓取失败:', error));

综合优化示例

下面是一个结合所有优化方案的综合示例:

javascript Copy
import puppeteer, {KnownDevices} from 'puppeteer-core';

const scrapelessUrl = 'wss://browser.scrapeless.com/browser?token=your_api_key&session_ttl=180&proxy_country=ANY';

async function optimizedScraping(url) {
    console.log(`开始优化抓取: ${url}`);

    // 记录流量使用
    let totalBytesUsed = 0;

    const browser = await puppeteer.connect({
        browserWSEndpoint: scrapelessUrl,
        defaultViewport: null
    });

    const page = await browser.newPage();

    // 设置移动设备模拟
    const iPhone = KnownDevices['iPhone 15 Pro'];
    await page.emulate(iPhone);

    // 设置请求拦截
    await page.setRequestInterception(true);

    // 定义要阻止的资源类型
    const BLOCKED_TYPES = [
        'image',
        'media',
        'font'
    ];

    // 定义要阻止的域
    const BLOCKED_DOMAINS = [
        'google-analytics.com',
        'googletagmanager.com',
        'facebook.net',
        'doubleclick.net',
        'adservice.google.com'
    ];

    // 定义要阻止的路径
    const BLOCKED_PATHS = [
        '/ads/',
        '/analytics/',
        '/tracking/'
    ];

    // 拦截请求
    page.on('request', (request) => {
        const url = request.url();
        const resourceType = request.resourceType();

        // 检查资源类型
        if (BLOCKED_TYPES.includes(resourceType)) {
            console.log(`阻止的资源类型: ${resourceType} - ${url.substring(0, 50)}...`);
            request.abort();
            return;
        }

        // 检查域
        if (BLOCKED_DOMAINS.some(domain => url.includes(domain))) {
            console.log(`阻止的域: ${url.substring(0, 50)}...`);
            request.abort();
            return;
        }

        // 检查路径
        if (BLOCKED_PATHS.some(path => url.includes(path))) {
            console.log(`阻止的路径: ${url.substring(0, 50)}...`);
            request.abort();
            return;
        }

        // 允许其他请求
        request.continue();
    });

    // 监控网络流量
    page.on('response', async (response) => {
        const headers = response.headers();
        const contentLength = headers['content-length'] ? parseInt(headers['content-length'], 10) : 0;
        totalBytesUsed += contentLength;
    });

    await page.goto(url, {waitUntil: 'domcontentloaded'});

    // 模拟滚动以触发懒加载内容
    await page.evaluate(() => {
        window.scrollBy(0, window.innerHeight);
    });

    await new Promise(resolve => setTimeout(resolve, 1000))

    // 提取数据
    const data = await page.evaluate(() => {
        return {
            title: document.title,
            content: document.body.innerText.substring(0, 1000),
            links: Array.from(document.querySelectorAll('a')).slice(0, 10).map(a => ({
                text: a.innerText,
                href: a.href
            }))
        };
    });

    // 输出流量使用统计
    console.log(`\n流量使用统计:`);
    console.log(`使用: ${(totalBytesUsed / 1024 / 1024).toFixed(2)} MB`);

    await browser.close();
    return data;
}

// 用法
optimizedScraping('https://www.scrapeless.com')
    .then(data => console.log('抓取完成:', data))
    .catch(error => console.error('抓取失败:', error));

优化比较

我们尝试从综合示例中移除优化代码以比较优化前后的流量。下面是未优化的示例代码:

javascript Copy
import puppeteer from 'puppeteer-core';

const scrapelessUrl = 'wss://browser.scrapeless.com/browser?token=your_api_key&session_ttl=180&proxy_country=ANY';

async function optimizedScraping(url) {
console.log(开始优化爬取: ${url});

// 记录流量使用情况
let totalBytesUsed = 0;

const browser = await puppeteer.connect({
browserWSEndpoint: scrapelessUrl,
defaultViewport: null
});

const page = await browser.newPage();

// 设置请求拦截
await page.setRequestInterception(true);

// 拦截请求
page.on('request', (request) => {
request.continue();
});

// 监控网络流量
page.on('response', async (response) => {
const headers = response.headers();
const contentLength = headers['content-length'] ? parseInt(headers['content-length'], 10) : 0;
totalBytesUsed += contentLength;
});

await page.goto(url, {waitUntil: 'domcontentloaded'});

// 模拟滚动以触发懒加载内容
await page.evaluate(() => {
window.scrollBy(0, window.innerHeight);
});

await new Promise(resolve => setTimeout(resolve, 1000))

// 提取数据
const data = await page.evaluate(() => {
return {
title: document.title,
content: document.body.innerText.substring(0, 1000),
links: Array.from(document.querySelectorAll('a')).slice(0, 10).map(a => ({
text: a.innerText,
href: a.href
}))
};
});

// 输出流量使用统计
console.log(\n流量使用统计:);
console.log(已使用: ${(totalBytesUsed / 1024 / 1024).toFixed(2)} MB);

await browser.close();
return data;
}

// 使用
optimizedScraping('https://www.scrapeless.com')
.then(data => console.log('爬取完成:', data))
.catch(error => console.error('爬取失败:', error));

Copy
运行未优化代码后,我们可以通过打印的信息直观地看到流量差异:

| 场景        | 使用流量 (MB) | 保存比例         |
|-------------|:-------------:|:----------------:|
| 未优化      |      6.03     |         —        |
| **优化**    |    **0.81**   |    **≈ 86.6 %**  |

通过结合上述优化方案,可以显著减少代理流量消耗,提高爬取效率,并确保获得所需的核心内容。

在Scrapeless,我们仅访问公开可用的数据,并严格遵循适用的法律、法规和网站隐私政策。本博客中的内容仅供演示之用,不涉及任何非法或侵权活动。我们对使用本博客或第三方链接中的信息不做任何保证,并免除所有责任。在进行任何抓取活动之前,请咨询您的法律顾问,并审查目标网站的服务条款或获取必要的许可。

最受欢迎的文章

目录