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

Node.js爬取Cloudflare保护的WebSocket失败求解决方案

解决DexScreener WebSocket 403错误的可行方案

先修正代码里的基础错误

你的代码里有几个不符合WebSocket标准的参数,这大概率是触发403的直接原因:

  • Sec-WebSocket-Version 必须设为13,这是当前WebSocket协议的唯一标准版本,你写的1会被服务器直接拒绝
  • Origin 应该是https://dexscreener.com(网页的源地址),而非WebSocket的wss://io.dexscreener.com
  • 没必要手动打乱TLS cipher顺序,这种操作反而容易被Cloudflare识别为异常请求

修正后的基础请求头示例:

const header = {
    'Sec-WebSocket-Key': this.generateWebSocketKey(),
    'Sec-WebSocket-Version': '13', // 修正为标准版本
    'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits',
    'Origin': 'https://dexscreener.com', // 修正为网页源
    'User-Agent': UserAgent.random().toString(),
};

核心问题:绕开Cloudflare的会话验证

Cloudflare对WebSocket连接的验证依赖前置HTTP会话的CF验证状态——你必须先通过Cloudflare的人机验证(哪怕是隐形的),拿到有效的cf_clearance Cookie和相关请求头,才能建立合法的WebSocket连接。

方案1:用无头浏览器自动处理CF验证(最可靠)

直接用Puppeteer或Playwright打开目标页面,让浏览器自动完成Cloudflare的验证流程,然后监听页面内的WebSocket消息。这种方法完全模拟真实用户行为,不需要手动处理任何CF参数:

示例代码(Puppeteer):

const puppeteer = require('puppeteer');

(async () => {
    const browser = await puppeteer.launch({ headless: 'new' });
    const page = await browser.newPage();

    // 监听页面内的所有WebSocket消息
    page.on('websocket', (ws) => {
        console.log('WebSocket连接建立');
        ws.on('message', (data) => {
            console.log('收到消息:', data.toString());
        });
        ws.on('close', () => {
            console.log('WebSocket连接关闭');
        });
    });

    // 打开目标页面,浏览器自动处理CF验证
    await page.goto('https://dexscreener.com/new-pairs');
    // 等待页面加载完成,确保WebSocket连接建立
    await page.waitForTimeout(5000);

    // 保持运行,直到手动终止
    // await browser.close();
})();

方案2:手动获取CF验证会话(适合无浏览器场景)

如果必须用纯Node.js的WebSocket客户端,需要先通过HTTP请求完成CF验证:

  1. 发送GET请求到https://dexscreener.com/new-pairs,带上真实的User-Agent
  2. 检查响应是否包含Cloudflare的Turnstile验证页面(状态码503或页面有cf-turnstile元素)
  3. 完成Turnstile验证(可使用专门的库或第三方验证服务)
  4. 提取验证后的cf_clearance Cookie和CF-RAY头
  5. 在WebSocket连接时,将这些Cookie和头加入请求头

示例代码框架:

const WebSocket = require('ws');
const axios = require('axios');
const crypto = require('crypto');
const UserAgent = require('user-agents');

async function getCFCredentials() {
    const userAgent = new UserAgent().toString();
    const response = await axios.get('https://dexscreener.com/new-pairs', {
        headers: { 'User-Agent': userAgent },
        maxRedirects: 5,
        withCredentials: true
    });

    // 此处需补充Turnstile验证逻辑,获取有效cf_clearance
    const cfClearance = response.headers['set-cookie']?.find(c => c.startsWith('cf_clearance'))?.split(';')[0];
    const cfRay = response.headers['cf-ray'];

    return { userAgent, cfClearance, cfRay };
}

async function connectWebSocket() {
    const { userAgent, cfClearance, cfRay } = await getCFCredentials();
    if (!cfClearance) {
        console.error('未获取到有效的CF验证Cookie');
        return;
    }

    const ws = new WebSocket('wss://io.dexscreener.com/dex/screener/pairs/h24/1?rankBy[key]=trendingScoreH6&rankBy[order]=desc&filters[pairAge][max]=24&filters[liquidity][min]=1000', {
        headers: {
            'User-Agent': userAgent,
            'Cookie': cfClearance,
            'CF-RAY': cfRay,
            'Origin': 'https://dexscreener.com',
            'Sec-WebSocket-Version': '13',
            'Sec-WebSocket-Key': crypto.randomBytes(16).toString('base64')
        }
    });

    ws.on('open', () => console.log('连接成功'));
    ws.on('message', (data) => console.log(data.toString()));
    ws.on('error', (err) => console.error('错误:', err));
}

connectWebSocket();

注意:手动处理Turnstile验证稳定性极低,Cloudflare的验证机制会持续更新,这种方法仅适合临时测试。

额外提示

  • 不要频繁更换User-Agent或请求参数,模拟真实用户的稳定行为
  • 如果使用代理,确保代理IP未被Cloudflare拉黑
  • 尽量保持WebSocket连接的生命周期与真实用户一致,避免频繁建立/断开连接

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:00:38