如何使用C#实现无直链动态触发式文件的下载功能
C# 实现NSE India站点动态CSV文件下载方案
这类点击页面按钮才触发的无公开直链下载,本质是站点做了请求来源校验:要求下载请求必须携带访问报表页时下发的会话Cookie、合法请求头,否则会被拦截。以下是两种可落地的实现方案,优先选HTTP模拟方案,性能更高:
方案1:HttpClient模拟请求(优先推荐,性能最优)
不需要启动浏览器,资源占用极低,适合批量调用场景:
- 第一步先抓包获取下载信息:打开浏览器F12开发者工具切换到「网络」面板,点击页面的
Download (.csv)按钮,找到对应下载请求,复制请求的实际URL、Referer、User-Agent字段即可。 - 第二步用HttpClient带Cookie容器模拟两次请求,先访问报表页拿到合法会话,再请求下载地址保存文件:
using System.Net; using System.Net.Http.Headers; // 全局初始化HttpClient,不要每次请求都新建 var handler = new HttpClientHandler { CookieContainer = new CookieContainer(), UseCookies = true, AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }; using var httpClient = new HttpClient(handler); // 配置通用请求头,模拟真实浏览器 httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"); httpClient.DefaultRequestHeaders.Accept.ParseAdd("text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8"); // 第一次请求:访问报表页,获取会话Cookie var reportPageUrl = "https://www.nseindia.com/reports/gsm"; var pageResponse = await httpClient.GetAsync(reportPageUrl); pageResponse.EnsureSuccessStatusCode(); // 第二次请求:请求抓包得到的CSV下载地址,配置Referer为报表页地址 var downloadUrl = "这里替换成你抓包拿到的实际CSV下载地址"; httpClient.DefaultRequestHeaders.Referrer = new Uri(reportPageUrl); var downloadResponse = await httpClient.GetAsync(downloadUrl); downloadResponse.EnsureSuccessStatusCode(); // 保存文件到本地 await using var fileStream = new FileStream("gsm_report.csv", FileMode.Create, FileAccess.Write, FileShare.None); await downloadResponse.Content.CopyToAsync(fileStream);
方案2:Puppeteer Sharp无头浏览器模拟点击(适配复杂反爬场景)
如果站点下载请求有JS动态生成的加密参数,抓包成本太高的话可以用这个方案,直接模拟真人点击操作,不需要分析接口逻辑:
- 先安装NuGet包:
PuppeteerSharp - 示例代码:
using PuppeteerSharp; // 首次运行会自动下载对应版本的Chromium using var browserFetcher = new BrowserFetcher(); await browserFetcher.DownloadAsync(); await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true }); await using var page = await browser.NewPageAsync(); // 访问报表页 await page.GoToAsync("https://www.nseindia.com/reports/gsm"); // 等待下载按钮加载完成,替换成你页面上下载按钮的正确CSS选择器 await page.WaitForSelectorAsync("button:contains('Download (.csv)')", new WaitForSelectorOptions { Timeout = 30000 }); // 监听下载事件 var downloadTask = page.WaitForDownloadAsync(); // 点击下载按钮 await page.ClickAsync("button:contains('Download (.csv)')"); // 等待下载完成 var download = await downloadTask; // 保存文件到本地指定路径 await download.SaveAsync("gsm_report.csv");
内容的提问来源于stack exchange,提问作者ashok
相关产品推荐
相关产品推荐

