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

使用Cypress测试站点地图链接时遇429拒绝服务错误,如何解决?

解决Cypress批量请求站点地图URL触发429限流的方案

1. 串行请求并添加间隔时间

直接并行遍历所有URL会瞬间发起大量请求,触发反爬机制。改成串行逐个请求,每个请求后添加等待时间,模拟正常用户的浏览节奏。

let results = [];

cy.request('sitemap.xml')
  .then(response => {
    return Cypress.$(response.body).find('loc')
      .toArray().map(el => el.innerText)
  })
  .then(urls => {
    // 递归串行处理每个URL
    const processNextUrl = (index) => {
      if (index >= urls.length) return;
      
      const currentUrl = urls[index];
      cy.request({
        url: currentUrl,
        failOnStatusCode: false,
        // 模拟真实浏览器请求头,避免被识别为爬虫
        headers: {
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
          'Referer': new URL(currentUrl).origin // 添加上游域名作为Referer
        }
      })
      .then(response => {
        results.push({ url: currentUrl, status: response.status });
      })
      .wait(1000) // 每个请求间隔1秒,可根据网站限流规则调整
      .then(() => processNextUrl(index + 1));
    };

    processNextUrl(0);
  })

2. 分批次请求+批次间隔

如果串行速度太慢,可以将URL分成小批次,每批次并行请求,批次之间添加较长等待时间,平衡效率和限流风险。

let results = [];

cy.request('sitemap.xml')
  .then(response => {
    return Cypress.$(response.body).find('loc')
      .toArray().map(el => el.innerText)
  })
  .then(urls => {
    const batchSize = 10; // 每批次处理10个URL
    const urlBatches = [];
    
    // 将URL数组分割为多个批次
    for (let i = 0; i < urls.length; i += batchSize) {
      urlBatches.push(urls.slice(i, i + batchSize));
    }

    // 递归处理每个批次
    const processNextBatch = (batchIndex) => {
      if (batchIndex >= urlBatches.length) return;
      
      const currentBatch = urlBatches[batchIndex];
      // 并行处理当前批次的所有请求
      Cypress.Promise.all(
        currentBatch.map(url => 
          cy.request({
            url,
            failOnStatusCode: false,
            headers: {
              'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
            }
          }).then(res => results.push({ url, status: res.status }))
        )
      )
      .wait(5000) // 批次之间间隔5秒,可按需调整
      .then(() => processNextBatch(batchIndex + 1));
    };

    processNextBatch(0);
  })

3. 用Node.js任务(Node Task)控制并发

Cypress的命令队列在浏览器环境运行,限流控制不够灵活。可以借助Node.js任务,用专业的限流库(如p-limit)精准控制并发数,同时避开浏览器的请求限制。

步骤1:安装依赖

npm install p-limit --save-dev

步骤2:配置Cypress任务(cypress.config.js)

const { defineConfig } = require('cypress');
const pLimit = require('p-limit');

module.exports = defineConfig({
  e2e: {
    setupNodeEvents(on, config) {
      on('task', {
        async checkSitemapUrls({ urls }) {
          const limit = pLimit(5); // 限制同时发起5个请求
          const results = await Promise.all(
            urls.map(url => limit(async () => {
              try {
                const response = await fetch(url, {
                  headers: {
                    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36'
                  }
                });
                return { url, status: response.status };
              } catch (error) {
                return { url, status: 'error', message: error.message };
              }
            }))
          );
          return results;
        }
      });
    },
  },
});

步骤3:在测试代码中调用任务

cy.request('sitemap.xml')
  .then(response => {
    return Cypress.$(response.body).find('loc')
      .toArray().map(el => el.innerText)
  })
  .then(urls => {
    cy.task('checkSitemapUrls', { urls }).then(results => {
      // 处理最终结果,比如打印或断言
      console.log('站点地图URL检测结果:', results);
    });
  })

额外注意事项

  • 调整间隔/并发数:根据目标网站的限流规则灵活调整,比如有些网站可能需要2秒以上的间隔,或者更低的并发数。
  • 检查robots.txt:确认目标网站允许爬取站点地图中的URL,避免违反爬虫协议。
  • 白名单权限:如果测试的是自家网站,可以联系运维团队将测试IP加入限流白名单,从根源解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 13:50:21