使用WebClient获取parkrun页面HTML遇反爬问题求助
解决parkrun页面爬取的反爬问题
问题分析
你遇到的是网站的反爬机制:WebClient基础请求会被识别为非浏览器,添加请求头后仍触发人机验证,大概率是因为缺少会话Cookie,或者网站需要JavaScript执行来完成验证流程。
方案一:用HttpClient+CookieContainer模拟完整会话
WebClient默认不持久化Cookie,而很多反爬系统会通过首次请求下发会话标识,后续请求需要携带这些Cookie才能通过验证。下面是实现代码:
using System; using System.Net; using System.Net.Http; using System.Threading.Tasks; class ParkrunScraper { static async Task Main(string[] args) { var cookieContainer = new CookieContainer(); using var handler = new HttpClientHandler { CookieContainer = cookieContainer }; using var client = new HttpClient(handler); // 配置和真实浏览器一致的请求头 client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"); client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"); client.DefaultRequestHeaders.Add("Accept-Language", "en-GB,en;q=0.9,en-US;q=0.8"); client.DefaultRequestHeaders.Add("Accept-Encoding", "gzip, deflate, br"); client.DefaultRequestHeaders.Add("Cache-Control", "max-age=0"); client.DefaultRequestHeaders.Add("Connection", "keep-alive"); // 先请求目标页面的父页面,获取必要的会话Cookie var initialResponse = await client.GetAsync("https://www.parkrun.com.au/lewisparkreserve/"); initialResponse.EnsureSuccessStatusCode(); // 再请求最新结果页面 var targetResponse = await client.GetAsync("https://www.parkrun.com.au/lewisparkreserve/results/latestresults/"); targetResponse.EnsureSuccessStatusCode(); var htmlContent = await targetResponse.Content.ReadAsStringAsync(); Console.WriteLine(htmlContent); } }
方案二:用Selenium模拟真实浏览器(绕过JavaScript验证)
如果方案一仍触发人机验证,说明网站用了基于JavaScript的反爬(比如Cloudflare),这时需要用无头浏览器完全模拟用户行为:
- 先安装NuGet包:
Selenium.WebDriver和Selenium.WebDriver.ChromeDriver - 编写代码:
using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI; using System; class ParkrunBrowserScraper { static void Main(string[] args) { var chromeOptions = new ChromeOptions(); // 无头模式运行,不弹出浏览器窗口 chromeOptions.AddArgument("--headless=new"); chromeOptions.AddArgument("--disable-gpu"); chromeOptions.AddArgument("--no-sandbox"); // 设置语言,和浏览器一致 chromeOptions.AddUserProfilePreference("intl.accept_languages", "en-GB,en;q=0.9,en-US;q=0.8"); // 模拟真实User-Agent chromeOptions.AddArgument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"); using var driver = new ChromeDriver(chromeOptions); // 设置页面加载超时 driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(20); driver.Navigate().GoToUrl("https://www.parkrun.com.au/lewisparkreserve/results/latestresults/"); // 等待页面加载完成(如果有人机验证,可能需要手动处理滑块,但parkrun的验证通常较简单) var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(15)); wait.Until(d => d.FindElement(By.CssSelector(".results-table"))); // 等待结果表格加载 var pageHtml = driver.PageSource; Console.WriteLine(pageHtml); } }
注意事项
- 爬取前务必查看网站的
robots.txt和使用条款,确保行为合规。 - 即使单次请求,也不要过度频繁访问,避免触发IP封禁。
- Selenium方案中,ChromeDriver版本要和本地Chrome浏览器版本匹配,否则会报错。
内容的提问来源于stack exchange,提问作者user1478785
相关产品推荐
相关产品推荐

