如何处理带有reCAPTCHA验证的FortiGuard网站自动POST请求?
我来帮你拆解问题并给出可行的解决方案:
首先你碰到的是隐形reCAPTCHA——就是那种无需用户手动点击验证框的验证机制。它的核心逻辑是:当你在浏览器打开页面时,Google的reCAPTCHA脚本会自动运行,生成一个加密的验证token(通常是g-recaptcha-response参数),这个token会和表单数据一起提交到服务器做校验。而你用WebClient的方式是纯HTTP请求,没有JavaScript执行环境,自然拿不到这个必需的token,所以服务器才会返回"Empty captcha"。
下面给你两种实用的解决思路:
方案一:用浏览器自动化工具模拟真实操作(最推荐)
这种方法完全复刻用户在浏览器里的操作流程,能自动触发reCAPTCHA的验证逻辑,生成合法的token。我推荐用Selenium,它支持多种浏览器,在C#里实现起来也很顺畅。
具体步骤:
- 先通过NuGet安装两个依赖包:
Selenium.WebDriver和Selenium.WebDriver.ChromeDriver(对应Chrome浏览器,你也可以换成Firefox等其他驱动)。 - 编写模拟脚本:
using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI; // 配置Chrome选项,可选开启无头模式(不显示浏览器窗口) var chromeOptions = new ChromeOptions(); chromeOptions.AddArgument("--headless=new"); // 新版Chrome的无头模式参数 using (var driver = new ChromeDriver(chromeOptions)) { // 打开目标提交页面 driver.Navigate().GoToUrl("https://www.fortiguard.com/faq/wfratingsubmit"); // 等待页面加载完成,确保表单元素和reCAPTCHA脚本都初始化完毕 var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); wait.Until(d => d.FindElement(By.Name("url"))); // 逐一填写表单字段 driver.FindElement(By.Name("url")).SendKeys("testwebsite.com"); driver.FindElement(By.Name("categorysuggestion")).SendKeys("category"); driver.FindElement(By.Name("name")).SendKeys("myname"); driver.FindElement(By.Name("email")).SendKeys("myemail"); driver.FindElement(By.Name("company")).SendKeys("mycompany"); // 等待隐形reCAPTCHA自动生成验证token wait.Until(d => { // 执行JS获取reCAPTCHA的响应值 var token = d.ExecuteScript("return document.getElementById('g-recaptcha-response').value;"); return token != null && !string.IsNullOrWhiteSpace(token.ToString()); }); // 提交表单 driver.FindElement(By.CssSelector("button[type='submit']")).Click(); // 获取提交后的响应页面内容 var responseContent = driver.PageSource; // 这里可以根据需求处理响应内容,比如提取结果信息 Console.WriteLine(responseContent); }
这个方案的优势是稳定可靠,因为完全模拟了真实用户的操作路径,reCAPTCHA会自动通过验证,服务器很难识别出是自动化脚本(只要你不频繁批量操作,避免触发反爬机制)。
方案二:手动抓取token并模拟请求(不推荐,易失效)
如果你不想用浏览器自动化,也可以尝试临时抓取验证所需的参数,但这个方法非常不稳定——因为reCAPTCHA的token有有效期,而且服务器会严格校验请求的上下文(比如Cookie、User-Agent等):
- 打开浏览器开发者工具(F12),访问目标页面,手动填写表单并提交。
- 在Network标签里找到对应的POST请求,查看Form Data,复制
g-recaptcha-response参数的值,同时复制请求头里的Cookie、User-Agent等关键信息。 - 用
WebClient或者HttpClient模拟请求时,把这些参数和请求头完整带上。
但要注意:这个token几分钟就会过期,而且Google会检测请求的来源一致性,一旦你的请求上下文和浏览器不一致,服务器就会拒绝请求,所以这个方法只能临时应急,不适合长期自动化场景。
最后提醒一句:请确保你的自动化行为符合FortiGuard的服务条款,不要频繁提交请求,避免被封禁IP哦。
备注:内容来源于stack exchange,提问作者onur

