You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core API如何模拟浏览器请求自动下载外部URL的ZIP文件

问题描述

我正在开发一个ASP.NET Core Web API,用于接收和处理XML文件,目前该API会将这些文件存储在本地文件夹和Amazon AWS中。我已成功从XML文件中提取出一个URL,目标是自动从该URL下载ZIP文件。

手动操作流程如下:

  • 打开XML文件。
  • 在XML中定位该URL。
  • 在浏览器中访问该URL。

该URL会打开一个空白窗口,执行验证后触发ZIP文件的自动下载。由于该URL由外部公司提供,我无法获取触发下载的具体代码。

我尝试了以下代码实现,但未成功:

using (var stream = file.OpenReadStream())
using (var reader = new StreamReader(stream))
{
    string xmlContent = await reader.ReadToEndAsync();

    // Parsear el XML para obtener el enlace dinámico
    XDocument xmlDocument = XDocument.Parse(xmlContent);
    string zipUrl = xmlDocument.Descendants("URL").FirstOrDefault()?.Value;

    if (!string.IsNullOrEmpty(zipUrl))
    {
        try
        {
            if (!string.IsNullOrEmpty(zipUrl))
            {
                await _download.DownloadZipFiles(zipUrl, "archivo.zip");
            }
            else
            {
                orderRepository.LogError(null, 422, "Ocurrio un error al ingresar a la url.", zipUrl);
            }
        }
        catch (Exception ex)
        {
            // Manejar cualquier error que pueda ocurrir al intentar abrir la URL
            var errMsg = $"Error al abrir la URL: {ex.Message}";
            orderRepository.LogError(null, 400, errMsg, cxmlFileName);
            await IntentoDePedidoCorreo();
            return FillResponse(payloadId, timestamp, "400", errMsg, errMsg);
        }
    }
    else
    {
        var errMsg = "No se encontró la URL en el archivo XML.";
        orderRepository.LogError(null, 400, errMsg, cxmlFileName);
        await IntentoDePedidoCorreo();
        return FillResponse(payloadId, timestamp, "400", errMsg, errMsg);
    }
}

调用的类代码如下:

public async Task DownloadZipFiles(string url, string fileName)
{
    using (HttpClient httpClient = new HttpClient())
    {
        HttpResponseMessage response = await httpClient.GetAsync(url);
        if (response.IsSuccessStatusCode)
        {
            using (Stream contentStream = await response.Content.ReadAsStreamAsync())
            using (FileStream fileStream = File.Create(fileName))
            {
                await contentStream.CopyToAsync(fileStream);
            }
        }
    }
}

上述代码返回损坏的ZIP文件,将其转换为HTML后发现,实际返回的是该URL对应页面的部分HTML和JavaScript代码。

现寻求指导,请问有哪些库或方法可以模拟浏览器访问该URL,以实现自动下载ZIP文件的功能?


解决方案

问题核心在于HttpClient仅会获取目标URL的初始静态内容,不会执行页面中的JavaScript验证逻辑,而目标URL需要通过浏览器执行JS完成验证后才会触发ZIP下载。以下是几种可行的解决方案:

1. 使用Playwright(推荐)

Playwright是微软推出的浏览器自动化工具,可完整模拟Chrome、Firefox等浏览器的所有行为,包括执行JS、处理页面跳转、Cookie管理等,完全匹配你的手动操作流程。

实现步骤:

  • 安装NuGet包:Microsoft.Playwright
  • 编写代码实现下载:
using Microsoft.Playwright;

public async Task DownloadZipWithPlaywright(string url, string savePath)
{
    using var playwright = await Playwright.CreateAsync();
    await using var browser = await playwright.Chromium.LaunchAsync(new BrowserTypeLaunchOptions
    {
        Headless = true, // 启用无头模式,无需显示浏览器窗口
    });
    var page = await browser.NewPageAsync();

    // 监听下载事件,等待页面触发下载
    var downloadTask = page.WaitForDownloadAsync();
    await page.GotoAsync(url);
    var download = await downloadTask;

    // 将下载的文件保存到指定路径
    await download.SaveAsAsync(savePath);
}

2. 使用Selenium WebDriver

Selenium是老牌浏览器自动化工具,同样支持完整模拟浏览器行为,适合熟悉该工具的开发者。

实现步骤:

  • 安装NuGet包:Selenium.WebDriver以及对应浏览器的驱动(如Selenium.WebDriver.ChromeDriver)
  • 编写代码实现下载:
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

public async Task DownloadZipWithSelenium(string url, string savePath)
{
    var options = new ChromeOptions();
    options.AddArgument("--headless=new"); // 启用无头模式
    // 配置下载路径,跳过下载弹窗
    var downloadPrefs = new Dictionary<string, object>
    {
        {"download.default_directory", Path.GetDirectoryName(savePath)},
        {"download.prompt_for_download", false}
    };
    options.AddUserProfilePreference("download", downloadPrefs);

    using var driver = new ChromeDriver(options);
    driver.Navigate().GoToUrl(url);

    // 根据页面验证逻辑的耗时,调整等待时间
    await Task.Delay(5000);

    // 处理动态文件名:找到下载目录中最新的文件并重命名
    var downloadDir = Path.GetDirectoryName(savePath);
    var latestFile = new DirectoryInfo(downloadDir).GetFiles()
        .OrderByDescending(f => f.CreationTime).First();
    latestFile.MoveTo(savePath);
}

3. 抓包分析请求(轻量替代方案)

若不想使用浏览器自动化工具,可通过抓包工具(如Chrome开发者工具、Fiddler)手动分析请求流程:

  • 手动访问目标URL,记录浏览器触发下载前的所有请求细节(包括请求头、Cookie、最终的ZIP文件真实URL)
  • 使用HttpClient模拟这些请求,直接请求最终的ZIP文件URL,需注意携带与浏览器一致的User-Agent、Cookie等请求头,避免被服务器识别为非浏览器请求

这种方案更轻量,但需要拆解目标网站的验证逻辑,适合下载链接相对固定的场景。


内容的提问来源于stack exchange,提问作者Abraham Abraham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 01:37:50