如何从Nasdaq OMX Nordic爬取数据?Html Agility Pack及代理请求遇阻
解决纳斯达克北欧ETN数据爬取的无效请求问题
我之前也踩过ASP.NET站点爬取的坑,你已经找对了核心接口,现在的问题大概率是请求缺少关键验证信息或者头字段不匹配导致的,给你梳理下具体的解决思路和步骤:
1. 必须照搬浏览器的完整请求头
这类站点的反爬机制会严格校验请求的合法性,Postman默认的请求头和浏览器实际发送的差异很大。你需要:
- 打开浏览器开发者工具(F12),切换到「网络」标签,刷新原页面后找到那个POST到
DataFeedProxy.aspx的请求条目 - 复制该请求的所有请求头,包括
User-Agent、Referer、Cookie、X-Requested-With(如果存在)、Content-Type等,完全复刻进Postman里
2. 表单数据要包含动态生成的ASP.NET验证字段
ASP.NET站点会在页面中生成隐藏的验证字段,这些是请求必填项,比如:
__VIEWSTATE__EVENTVALIDATION__VIEWSTATEGENERATOR
这些字段的值是动态变化的,你得先访问原页面(http://www.nasdaqomxnordic.com/etp/etn/etninfo?Instrument=SSE132883),从页面HTML里提取这些字段的值,再把它们加入到表单数据中,不能只传你最初看到的部分参数。
3. 维持会话的一致性
很多站点用Cookie跟踪会话,你需要先GET原页面,获取服务器返回的Cookie,然后在POST请求时携带相同的Cookie,服务器才会认为这是一个合法的会话请求。
代码实现示例(C# + HtmlAgilityPack)
如果用C#来实现,完整流程大概是这样:
using HtmlAgilityPack; using System.Net.Http; using System.Collections.Generic; using System.Threading.Tasks; public async Task<string> FetchEtnPrice() { var client = new HttpClient(new HttpClientHandler { UseCookies = true }); // 自动维持Cookie会话 // 第一步:访问原页面,提取验证字段 var originalPage = await client.GetAsync("http://www.nasdaqomxnordic.com/etp/etn/etninfo?Instrument=SSE132883"); var pageHtml = await originalPage.Content.ReadAsStringAsync(); var doc = new HtmlDocument(); doc.LoadHtml(pageHtml); // 抓取ASP.NET动态验证字段 var viewState = doc.DocumentNode.SelectSingleNode("//input[@name='__VIEWSTATE']")?.GetAttributeValue("value", ""); var eventValidation = doc.DocumentNode.SelectSingleNode("//input[@name='__EVENTVALIDATION']")?.GetAttributeValue("value", ""); // 第二步:构造完整表单数据(补充抓包看到的所有参数) var formData = new Dictionary<string, string> { ["__VIEWSTATE"] = viewState, ["__EVENTVALIDATION"] = eventValidation, ["Instrument"] = "SSE132883", // 这里添加你从抓包中看到的其他表单参数,比如Action、Method等 }; // 设置请求头,完全匹配浏览器发送的内容 client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36"); client.DefaultRequestHeaders.Referrer = new Uri("http://www.nasdaqomxnordic.com/etp/etn/etninfo?Instrument=SSE132883"); // 第三步:发送POST请求 var response = await client.PostAsync("http://www.nasdaqomxnordic.com/webproxy/DataFeedProxy.aspx", new FormUrlEncodedContent(formData)); return await response.Content.ReadAsStringAsync(); }
额外注意事项
- 不要频繁发送请求,避免触发反爬机制导致IP被封禁
- 部分站点的表单参数会包含时间戳或随机值,需要每次请求都重新从页面或响应中获取
- 如果还是失败,可以对比抓包请求和你发送的请求,检查参数顺序、编码方式(比如是否是
application/x-www-form-urlencoded)是否一致
内容的提问来源于stack exchange,提问作者user2202098
相关产品推荐
相关产品推荐

