使用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
相关产品推荐
相关产品推荐

