当前位置: 首页 > news >正文

优化无头浏览器流量:使用Puppeteer进行高效数据抓取的成本降低策略

概述

使用 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媒体文件视频/音频文件媒体内容无法播放⭐ 安全
manifestWeb 应用清单PWA 配置文件PWA 功能可能受到影响⭐ 安全
prefetch预取资源<link rel="prefetch">对页面影响很小⭐ 安全
stylesheetCSS 样式表外部 CSS 文件页面样式丢失,可能影响布局⚠️ 注意
websocketWebSocket实时通信连接实时功能被禁用⚠️ 注意
eventsource服务器发送事件服务器推送数据推送功能被禁用⚠️ 注意
preflightCORS 预检请求OPTIONS 请求跨域请求失败⚠️ 注意
scriptJavaScript 脚本外部 JS 文件动态功能被禁用,SPA 可能无法渲染❌ 避免
xhrXHR 请求AJAX 数据请求无法获取动态数据❌ 避免
fetchFetch 请求现代 AJAX 请求无法获取动态数据❌ 避免
document主文档HTML 页面本身页面无法加载❌ 避免

推荐级别说明:

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

资源拦截示例代码

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));
 

优化方案 2:请求 URL 拦截

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

URL 拦截策略

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

常见可拦截 URL 模式

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

URL 拦截示例代码

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));
 

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

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

移动设备模拟的优势

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

移动设备模拟配置

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

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

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

import { KnownDevices } from 'puppeteer-core';
const iPhone = KnownDevices['iPhone 15 Pro'];
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.emulate(iPhone);
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));
 

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

场景使用流量 (MB)节省比率
未优化6.03
优化后0.81≈ 86.6 %

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

http://www.xdnf.cn/news/178291.html

相关文章:

  • PHP实现 Apple ID 登录的服务端验证指南
  • 现代Python打包工具链
  • Redis的阻塞
  • AI赋能智能对讲机:技术融合与行业变革的深度实践
  • 【计算机网络性能优化】从基础理论到实战调优
  • 97A6-ASEMI无人机专用功率器件97A6
  • (25)VTK C++开发示例 --- 将点坐标写入.xyz文件
  • Java基础 — 数组
  • Spark-Streaming(四)
  • 天梯——现代战争
  • NTFS和EXFAT哪个好:深入解析这两种文件系统的优劣
  • FAQ运用
  • 在使用docker创建容器运行报错no main manifest attribute, in app.jar
  • springboot logback 默认加载配置文件顺序
  • Leetcode:283. 移动零
  • 【大模型微调与应用开发实战指南】从理论到工业级部署
  • COMSOL多孔介质自然对流与传热现象的仿真研究
  • 《原神/星穹铁道私服怎么建?内网穿透+本地调试完整指南》
  • 【Vue】单元测试(Jest/Vue Test Utils)
  • 高德地图 API 拿到当前定位和目的地址转经纬度,实现路径规划
  • django filter 排除字段
  • C++学习:六个月从基础到就业——模板编程:类模板
  • 淘宝tb.cn短链接生成
  • 基于ruoyi-plus实现AI聊天和绘画
  • 前端面试 js
  • 考研系列-计算机组成原理第六章、总线
  • 国标GB28181视频平台EasyCVR助力打造太阳能供电远程视频监控系统
  • 2025系统架构师---数据库架构风格
  • 多模态大语言模型arxiv论文略读(四十四)
  • Laravel5.7的一些用法