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

使用Playwright在C#中发送POST请求遇Cloudflare验证问题

解决Playwright APIRequest触发Cloudflare验证的问题

你遇到的问题核心是:Playwright的APIRequest模块仅发送纯HTTP请求,没有模拟真实浏览器执行JavaScript的环境,而Cloudflare会检测请求是否来自能正常执行JS的真实浏览器环境,因此直接用APIRequest发送POST会被拦截,返回验证页面。

以下是具体解决步骤:

1. 先通过浏览器页面完成Cloudflare验证

在发送API请求前,先用Playwright打开目标域名的页面,等待页面加载完成(确保Cloudflare验证通过),这样浏览器上下文会保存验证后的Cookie,后续APIRequest会复用这些Cookie。

修改你的初始化方法,添加验证步骤:

public async Task InitializePlaywrightAsync(string targetDomain)
{
    _playwright = await Playwright.CreateAsync();
    // 使用新的无头模式(更接近真实浏览器,降低被检测概率)
    _browser = await _playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions 
    { 
        Headless = BrowserTypeLaunchOptionsHeadless.New,
        Args = new[] { "--disable-blink-features=AutomationControlled" } // 禁用自动化检测标识
    });
    _context = await _browser.NewContextAsync(new BrowserNewContextOptions
    {
        ViewportSize = new ViewportSize { Width = 1920, Height = 1080 },
        Locale = "en-US",
        TimezoneId = "America/New_York"
    });

    // 打开目标域名页面,完成Cloudflare验证
    var page = await _context.NewPageAsync();
    await page.GotoAsync(targetDomain);
    // 等待页面加载完成,可根据实际情况调整等待条件,比如等待某个元素出现
    await page.WaitForLoadStateAsync(LoadState.NetworkIdle);
    await page.CloseAsync();
}

2. 优化APIRequest请求配置

确保请求的Headers和真实浏览器完全一致,同时避免手动设置可能暴露自动化的Header,建议直接复用浏览器上下文的默认Headers,仅补充必要内容。

修改PostToUrlAsJObject方法:

private async Task<JObject?> PostToUrlAsJObject(string url, StringContent content)
{
    try
    {
        string con = await content.ReadAsStringAsync();
        var response = await _context.APIRequest.PostAsync(url, new()
        {
            DataString = con,
            // 优先复用浏览器上下文的默认Headers,仅补充必要的内容
            Headers = new Dictionary<string, string>
            {
                { "Content-Type", "application/json" },
                { "Accept", "application/json" }
            },
        });

        string res = await response.TextAsync();
        // 先检查返回内容是否是Cloudflare验证页面
        if (res.Contains("Cloudflare") || res.Contains("cf-turnstile"))
        {
            Console.WriteLine("Cloudflare验证未通过,请检查页面验证步骤是否完成");
            return null;
        }
        return JObject.Parse(res);
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error during POST request:\r\nURL: {url}\r\nError: {ex.Message}\r\nStack Trace: {ex.StackTrace}");
        return null;
    }
}

3. 其他注意事项

  • 不要使用旧版的Headless = true,改用Headless = BrowserTypeLaunchOptionsHeadless.New,该模式更接近真实Chrome无头浏览器的行为。
  • 如果目标网站的Cloudflare验证需要交互(比如点击验证按钮),可以在页面加载后添加对应的交互代码,比如:
// 等待验证按钮出现并点击
await page.WaitForSelectorAsync("#cf-turnstile-container");
await page.ClickAsync("#cf-turnstile-container");
await page.WaitForLoadStateAsync(LoadState.NetworkIdle);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:05:05