每一个多余的爬虫流量都是要么支付给代理提供商的费用,要么是面临流量限制和IP被封的风险。如果您通过数百个代理地址从Wildberries、Ozon收集价格或监控Avito上的广告,流量节省直接影响项目预算。本文将介绍具体的技术方法,可以将传输数据量减少4-5倍,同时保持提取信息的完整性和准确性。
为什么爬虫流量影响预算
大多数代理提供商根据传输的千兆字节收费,而不是使用时间。如果您的爬虫完全加载Wildberries的产品页面——包括图片、推荐脚本、分析跟踪器和字体——您为每个产品支付2-3MB的费用,而实际上只需要15-20KB的文本:名称、价格、评分、库存。
当每天扩展到50,000-100,000个产品时,“加载所有内容”和“仅加载所需内容”之间的差异每天会转化为数十GB的多余流量。这不仅增加了代理费用,还增加了目标网站的负担,从而增加了被反机器人保护措施拦截的风险,可能会导致验证码或临时IP封禁。流量优化既是节省资金,也是降低封禁风险。
还有第三个效果:每个请求传输的数据越少,请求执行的速度就越快。这可以增加并行性——在相同数量的代理上启动更多线程,而不超过反检测浏览器(如Dolphin Anty或AdsPower)在处理会话时设定的速度限制。
方法1:阻止图片、CSS和字体
如果爬虫通过无头浏览器(Playwright、Puppeteer、Selenium)工作,减少流量的最快方法是阻止加载不影响DOM中数据的静态资源。产品图片、网站字体、视频和CSS样式占据了页面重量的70%,但在提取文本和属性时并不参与。
from playwright.sync_api import sync_playwright
def block_heavy_resources(route, request):
if request.resource_type in ["image", "media", "font", "stylesheet"]:
route.abort()
else:
route.continue_()
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page()
page.route("**/*", block_heavy_resources)
page.goto("https://example.com/product/123")
html = page.content()
browser.close()
在Puppeteer中,通过page.setRequestInterception(true)实现类似的逻辑,在Selenium中通过设置Chrome配置文件的参数profile.managed_default_content_settings.images: 2。在实践中,这个设置可以在解析市场时立即减少50%到70%的流量,因为这些页面被视觉内容和广告横幅过载。
方法2:使用HTTP请求代替完整浏览器
许多人在不需要的地方使用Selenium或Playwright。如果页面不需要执行JavaScript来呈现数据(可以通过打开“查看页面源代码”而不是DevTools轻松检查),直接通过Python库requests或httpx获取HTML会更划算。这样的请求重量为千字节,而不是兆字节,因为它不涉及浏览器渲染引擎的调用、网络请求和次要资源。
import httpx
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"Accept-Encoding": "gzip, br",
"Accept": "text/html,application/xhtml+xml"
}
proxies = {"http://": "http://user:pass@proxy_host:port",
"https://": "http://user:pass@proxy_host:port"}
with httpx.Client(headers=headers, proxies=proxies, http2=True) as client:
response = client.get("https://example.com/catalog/item/456")
print(len(response.content), "字节已接收")
在网站提供完整HTML而不进行客户端渲染的情况下,从浏览器模拟转向直接HTTP请求可以将流量减少3-8倍。唯一的细节是,这种请求更容易与真实用户区分,因此对于具有严格反机器人保护的网站,最好将此方法与优质的住宅代理结合使用,这些代理提供真实家庭提供商的IP,降低请求被封的概率。
方法3:通过隐藏的JSON API进行解析
几乎所有现代市场——包括Wildberries、Ozon和Yandex.Market——通过前端调用的内部JSON API渲染产品卡片和列表。可以通过DevTools中的Network选项卡过滤XHR/Fetch类型的请求来找到这些端点。通常,一个这样的请求会返回5-30KB的JSON,包含纯数据:产品ID、价格、折扣、库存、评分——没有一字HTML标记或CSS。
完整HTML页面与直接调用JSON API之间传输数据量的差异可以达到10-15倍。额外的好处是,JSON更容易进行程序解析:不需要XPath选择器,只需通过字典的键访问所需字段。缺点是,这些端点通常需要特定的头部、会话令牌或请求签名参数,这些需要从主页面或移动应用程序中提取。
给实践者的建议
在围绕隐藏API构建爬虫之前,请通过代理拦截器(Charles Proxy、Fiddler)检查网站的移动版本或应用程序——移动API通常提供比桌面版本更紧凑和稳定的JSON。
方法4:Gzip和Brotli压缩
即使您不得不获取完整的HTML,启用正确的压缩也能将传输大小减少60-80%。许多自定义爬虫未发送头部Accept-Encoding: gzip, br,因此服务器返回未压缩的响应。库requests和httpx会自动解压Gzip和Brotli——只需在请求头中明确指示支持压缩即可。
Brotli在平均情况下比Gzip更强地压缩文本HTML,约15-20%,但并非所有服务器都支持此算法——应请求两种选项并允许服务器选择最佳方案。对于JSON API,压缩效果更为明显:重复的字典键(“price”、“name”、“rating”)几乎可以完美压缩,显著降低响应的重量。
方法5:条件请求和缓存
如果您每天多次监控同一产品的价格,大多数卡片在检查之间不会发生变化。使用头部If-Modified-Since和首次请求时获得的ETag值的If-None-Match。如果内容没有变化,服务器几乎不带响应体地返回304 Not Modified——在未更改的页面上节省流量可达95%。
import httpx
etag_store = {}
def fetch_with_cache(url, client):
headers = {}
if url in etag_store:
headers["If-None-Match"] = etag_store[url]
resp = client.get(url, headers=headers)
if resp.status_code == 304:
return None # 数据未改变
etag_store[url] = resp.headers.get("ETag", "")
return resp.content
并非所有网站都正确支持ETag,但对于那些支持的网站,这种方法成为在定期监控时减少流量的最有效方式——您实际上只为数据的真实变化付费,而不是重复加载未更改的内容。
方法6:选择性解析所需字段
有时无法减少来自服务器的输入流量——网站无论请求如何都会返回完整页面。在这种情况下,优化发生在处理阶段:不要仅仅为了提取另一个字段而重新加载页面。设计XPath或CSS选择器,使其在一次遍历DOM时提取所有所需属性——价格、名称、货号、库存、评分——而不是对同一URL进行不同爬虫的重复请求。
限制嵌套页面的遍历深度也是有用的。如果监控价格只需类别页面(商品列表)上的数据,则不要单独进入每个产品的卡片——这会产生重复流量,通常不会提供新信息,除了描述和评论,这些对价格和库存没有影响。
方法7:优化爬取模式
URL去重是一个基本但常被忽视的方法。市场目录生成许多具有相同内容但不同排序参数、UTM标签或会话ID的链接。在排队之前规范化URL(删除跟踪参数、排序查询参数)可以在遍历大型目录时消除10-30%的冗余请求。
根据数据变化频率优先遍历也能节省流量:对于需求高且价格波动大的商品,每小时检查一次,而对于稀缺商品则每天检查一次。这样的自适应计划比均匀遍历所有卡片的方式减少了2-4倍的请求总量,而不会失去关键数据的时效性。
如何与代理策略结合
减少流量直接影响代理类型的选择。如果您通过直接HTTP请求解析大量页面,而没有复杂的反机器人保护,快速且便宜的数据中心代理就足够了——它们在每千兆字节的低成本下提供高传输速度,这在每天大规模爬取成千上万的卡片时至关重要。
对于具有严格反机器人保护的网站,模拟真实用户行为非常重要,最好使用住宅代理——将其与阻止多余资源的方法结合使用,您将获得低流量和高信任度的请求。如果爬虫通过市场的移动版本API进行,数据更紧凑,反机器人系统针对移动IP范围,考虑使用移动代理以进一步降低封禁风险。
“每个请求的最小流量”+“适合任务的正确代理类型”的组合可以同时减少基础设施成本并提高数据收集速度,而不会降低可靠性。
方法比较表
| 方法 | 流量减少 | 实施难度 |
|---|---|---|
| 阻止图片/CSS/字体 | 50-70% | 低 |
| 使用HTTP请求代替浏览器 | 3-8倍 | 中等 |
| 隐藏的JSON API | 10-15倍 | 高 |
| Gzip/Brotli压缩 | 60-80% | 低 |
| 条件请求(ETag) | 在未更改的页面上可达95% | 中等 |
| URL去重和优先级 | 2-4倍 | 中等 |
实施清单
- 检查目标页面是否需要JavaScript渲染,或可以通过
httpx/requests直接获取HTML - 在无头浏览器中设置阻止image/media/font/stylesheet,如果仍然需要浏览器
- 通过DevTools → Network → XHR/Fetch找到内部JSON API
- 在所有请求中添加头部
Accept-Encoding: gzip, br - 实现ETag/Last-Modified的存储,以便在重复URL上进行条件请求
- 在爬取之前规范化和去重URL队列
- 根据数据的重要性和波动性设置自适应爬取频率
- 根据最终流量配置选择代理类型——数据中心、住宅或移动
结论
将爬虫流量减少5倍是一个现实的目标,如果按顺序应用这些方法:去除多余资源、在可能的情况下转向直接HTTP请求或JSON API、启用压缩、对未更改的数据使用条件请求并优化爬取模式。每一步都能产生可测量的效果,综合起来将彻底改变从市场和其他网站收集数据的项目经济。
在优化流量后,正确选择代理基础设施以适应新的负载配置非常重要。对于快速和便宜的大规模数据收集,适合使用数据中心代理,而对于与严格反机器人保护的网站进行交互,使用住宅代理,这些代理提供真实家庭提供商的IP地址,即使在高强度爬取时也能降低被封的风险。