You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何抓取动态加载的http://proxydb.net页面?Selenium CPU占用过高

解决动态页面抓取的高效方案(针对十万+页面的大型项目)

针对你遇到的proxydb.net因JS动态加载导致cURL返回空、Firefox驱动Selenium CPU占用过高的问题,结合大型爬虫项目的实践经验,我给你推荐几个可行方案,按资源效率从高到低排序:

1. 优先分析页面的后端API(最优解)

大多数动态加载页面的内容,其实是通过AJAX/Fetch请求从后端接口获取后渲染的。直接调用这些接口完全不需要渲染页面,资源占用极低、速度最快,最适合十万+级别的抓取需求。

操作步骤:

  • 打开Chrome/Firefox开发者工具(F12),切换到Network面板。
  • 刷新页面,过滤XHR或Fetch类型的请求,逐一查看返回内容,找到包含代理数据的接口。
  • 复制该接口的请求URL、请求头(尤其是Cookie、User-Agent、Referer等)和请求参数,用requests或aiohttp这类轻量级请求库直接发起请求。

注意事项:

  • 部分接口可能有反爬机制(比如签名参数、IP限制、Cookie有效期),需要模拟浏览器的请求逻辑,必要时用requests.Session保持会话。
  • 如果接口返回JSON数据,直接解析即可,比解析HTML效率高得多。

2. 使用Headless Chrome/Chromium + Puppeteer(高效且易实现)

相比Firefox驱动的Selenium,Headless Chrome结合Puppeteer的资源占用更低,API也更简洁,适合批量处理动态页面。通过配置参数,还能进一步降低CPU和内存消耗。

优化配置示例(Node.js代码):

const puppeteer = require('puppeteer');

(async () => {
  // 启动Headless Chrome,配置资源限制参数
  const browser = await puppeteer.launch({
    headless: 'new', // 新版无头模式,资源占用更低
    args: [
      '--disable-gpu', // 禁用GPU加速
      '--no-sandbox', // 禁用沙箱(部分环境需要)
      '--disable-dev-shm-usage', // 避免/dev/shm内存不足
      '--disable-extensions', // 禁用扩展
      '--disable-images', // 禁用图片加载,减少渲染压力
      '--blink-settings=imagesEnabled=false', // 同上
      '--window-size=800,600' // 缩小窗口尺寸,减少渲染区域
    ],
    defaultViewport: null,
    slowMo: 0 // 关闭延迟,加快速度
  });

  // 复用浏览器实例,批量处理页面
  for (let i = 0; i < 100; i++) {
    const page = await browser.newPage();
    await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36');
    await page.goto('http://proxydb.net', { waitUntil: 'domcontentloaded' }); // 等待DOM加载完成即可
    const html = await page.content(); // 获取渲染后的源码
    // 处理html逻辑...
    await page.close(); // 关闭页面释放资源
  }

  await browser.close();
})();

关键优化点:

  • 复用同一个浏览器实例,不要每次请求都启动新浏览器(这是Selenium CPU飙升的核心原因之一)。
  • 禁用图片、CSS等非必要资源加载,减少渲染工作量。
  • 使用domcontentloaded代替load作为等待条件,缩短等待时间。
  • 控制并发数,避免同时打开过多页面导致资源耗尽。

3. 使用Scrapy + Splash(适合Python生态的分布式爬虫)

如果你的项目基于Python的Scrapy框架,Splash是一个轻量级动态页面渲染服务(基于QtWebKit),资源占用远低于Selenium,还能部署成独立服务支持分布式调用。

核心配置:

  1. 安装并启动Splash服务:docker run -p 8050:8050 scrapinghub/splash
  2. 在Scrapy的settings.py中配置Splash:
SPLASH_URL = 'http://localhost:8050'
DOWNLOADER_MIDDLEWARES = {
    'scrapy_splash.SplashCookiesMiddleware': 723,
    'scrapy_splash.SplashMiddleware': 725,
    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}
SPIDER_MIDDLEWARES = {
    'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
  1. 在爬虫中使用Splash请求页面:
import scrapy
from scrapy_splash import SplashRequest

class ProxySpider(scrapy.Spider):
    name = 'proxy_spider'
    start_urls = ['http://proxydb.net']

    def start_requests(self):
        for url in self.start_urls:
            yield SplashRequest(
                url,
                callback=self.parse,
                args={'wait': 0.5, 'render_all': False}, # 只等待必要时间,不渲染所有资源
                headers={'User-Agent': 'Mozilla/5.0...'}
            )

    def parse(self, response):
        # 处理渲染后的response.body
        pass

4. 轻量级JS引擎:jsdom(适合简单动态页面)

如果页面的JS逻辑不复杂,可以用jsdom在Node.js环境中模拟DOM渲染,资源占用极低,但对复杂浏览器API(如Canvas、WebGL)支持有限。

示例代码:

const { JSDOM } = require('jsdom');

(async () => {
  const dom = await JSDOM.fromURL('http://proxydb.net', {
    runScripts: 'dangerously', // 允许执行页面JS
    resources: 'usable' // 加载必要资源
  });
  // 等待JS执行完成(可根据页面逻辑调整延迟)
  setTimeout(() => {
    const html = dom.serialize(); // 获取渲染后的源码
    // 处理html逻辑...
  }, 1000);
})();

最后,针对你的十万+页面需求,优先推荐方案1(API分析);如果无法找到可用接口,再选择方案2或3,这两个方案在合理配置下,完全可以支撑大规模抓取,不会出现CPU瞬间100%的问题。

内容的提问来源于stack exchange,提问作者Sven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 10:07:29