C#使用HtmlAgilityPack访问nseindia站点及下载文件超时问题咨询
问题原因
两个超时问题的共同根源是nseindia系列站点配置了严格的反爬虫策略,会校验所有HTTP请求的头字段与会话状态,未携带合法浏览器标识、来源页、会话Cookie的请求会被服务器直接丢弃,不会返回响应,因此触发超时错误。其他站点可正常访问是因为没有配置同等级的反爬校验,和HtmlAgilityPack本身功能无关。
解决方案
案例1:HtmlAgilityPack加载页面超时解决
修改代码逻辑,为HtmlWeb对象配置请求前拦截,补充合法的请求头参数,调整超时时间,修改后代码如下:
using System.Net; using HtmlAgilityPack; static void Main(string[] args) { // 安全协议配置提前到最前,确保生效 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; ExtractHref("https://www.nseindia.com/reports/gsm"); Console.ReadLine(); } static void ExtractHref(string URL) { HtmlWeb web = new HtmlWeb(); // 设置超时时间为30秒,可根据需求调整 web.Timeout = 30000; // 拦截请求添加头信息 web.PreRequest = (HttpWebRequest request) => { // 模拟Chrome浏览器的User-Agent request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"; // 补充来源页,模拟从站点首页跳转 request.Referer = "https://www.nseindia.com/"; request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"; request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"); request.KeepAlive = true; return true; }; HtmlDocument doc = web.Load(URL); // 提取链接逻辑不变,补充空判断避免无链接时报错 if (doc.DocumentNode.SelectNodes("//a[@href]") != null) { foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@href]")) { HtmlAttribute att = link.Attributes["href"]; if (att.Value.Contains("a")) { Console.WriteLine(att.Value); } } } }
案例2:xlsx文件下载超时解决
同样需要为WebClient补充请求头,且建议先请求一次站点主页面获取合法Cookie后再下载文件,修改后代码如下:
using System.Net; // 先创建Cookie容器保存会话 CookieContainer cookieContainer = new CookieContainer(); // 第一步:请求主页面获取Cookie HttpWebRequest homeRequest = (HttpWebRequest)WebRequest.Create("https://www.nseindia.com/"); homeRequest.CookieContainer = cookieContainer; homeRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"; homeRequest.Referer = "https://www.nseindia.com/"; using (HttpWebResponse homeResponse = (HttpWebResponse)homeRequest.GetResponse()) { // 空读取即可,自动保存Cookie到容器 } // 第二步:用带Cookie的WebClient下载文件 using (WebClient webClient = new WebClient()) { webClient.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"); webClient.Headers.Add("Referer", "https://www.nseindia.com/regulations/periodic-call-auction-illiquid-securities"); webClient.Headers.Add("Accept", "*/*"); // 把之前获取的Cookie加到请求头 webClient.Headers.Add("Cookie", cookieContainer.GetCookieHeader(new Uri("https://nseindia.com"))); // 超时时间设置为60秒,大文件可适当延长 webClient.DownloadFile("https://static.nseindia.com//s3fs-public/inline-files/contract_mas_illiquid_sec_12072021.xlsx", "Test.xlsx"); }
注意事项
- 不要频繁发起请求,站点可能会临时封禁你的IP
- User-Agent可以定期更新为当前主流浏览器的标识,避免被反爬策略识别
内容的提问来源于stack exchange,提问作者ashok
相关产品推荐
相关产品推荐

