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

如何使用Puppeteer Sharp下载PDF?弹窗PDFViewer访问问题求助

Puppeteer Sharp 弹窗PDFViewer下载问题解决方法

问题场景

目标网站点击锚点元素会弹出PDFViewer窗口,无直接PDF链接;尝试遍历浏览器页面获取弹窗对象时,调用WaitForSelectorAsync("#viewer")超时,无法操作下载按钮。

用户原始代码:

var pages = await browser.PagesAsync();

foreach (var p in pages) 
{
    if (p.Url.ToUpper().Contains("FILESTREAMER")) //url of the pdf viewer in the popup
    {
        await p.WaitForSelectorAsync("#viewer"); //times out
    }
}

解决方法

方法一:提前监听弹窗创建,避免遍历遗漏

不要等弹窗弹出后再遍历页面,提前注册TargetCreated事件,弹窗生成时直接捕获页面对象:

Page popupPage = null;
// 注册弹窗监听事件
browser.TargetCreated += async (sender, e) =>
{
    var target = e.Target;
    if (target.Type == TargetType.Page && target.Url.ToUpper().Contains("FILESTREAMER"))
    {
        popupPage = await target.PageAsync();
        // 等待弹窗网络加载完成
        await popupPage.WaitForLoadStateAsync(LoadState.NetworkIdle);
    }
};

// 点击触发弹窗的锚点元素
await mainPage.ClickAsync("你的锚点选择器");

// 等待弹窗页面对象初始化完成
while (popupPage == null)
{
    await Task.Delay(100);
}

// 尝试定位PDFViewer元素并点击下载
try
{
    await popupPage.WaitForSelectorAsync("#viewer", new WaitForSelectorOptions { Timeout = 10000 });
    // 替换为实际的下载按钮选择器
    await popupPage.ClickAsync("#downloadButton");
}
catch (TimeoutException)
{
    // 可尝试等待其他关键元素,或检查是否存在iframe嵌套
}

方法二:处理iframe嵌套的PDFViewer

多数网站的PDFViewer会放在iframe中,直接在弹窗页面查找元素会超时,需先定位iframe:

// 获取弹窗页面后,定位包含PDFViewer的iframe
var iframeElement = await popupPage.WaitForSelectorAsync("iframe[src*='FILESTREAMER']");
var pdfIframe = await iframeElement.ContentFrameAsync();

// 在iframe内操作PDFViewer
await pdfIframe.WaitForSelectorAsync("#viewer");
await pdfIframe.ClickAsync("下载按钮选择器");

方法三:直接拦截PDF网络请求(无需模拟点击)

跳过弹窗操作,直接拦截浏览器的PDF请求并保存文件:

// 开启请求拦截
await mainPage.SetRequestInterceptionAsync(true);
mainPage.Request += async (sender, e) =>
{
    var request = e.Request;
    // 判断请求是否为PDF资源
    if (request.ResourceType == ResourceType.Document || request.Url.EndsWith(".pdf"))
    {
        await request.ContinueAsync();
        var response = await request.ResponseAsync();
        var pdfBytes = await response.BufferAsync();
        // 保存PDF到本地
        File.WriteAllBytes("downloaded.pdf", pdfBytes);
    }
    else
    {
        await request.ContinueAsync();
    }
};

// 点击锚点触发PDF请求
await mainPage.ClickAsync("你的锚点选择器");

方法四:修改弹窗打开逻辑,在当前页加载PDF

如果弹窗是通过window.open打开的,可注入JS覆盖该方法,让PDF在当前页加载:

// 在主页面注入JS,替换window.open行为
await mainPage.EvaluateExpressionAsync(@"
    window.open = function(url) {
        window.location.href = url;
    }
");

// 点击锚点,PDF将在当前页加载
await mainPage.ClickAsync("你的锚点选择器");

// 等待页面加载完成后直接获取PDF内容
await mainPage.WaitForLoadStateAsync(LoadState.NetworkIdle);
var pdfBytes = await mainPage.PdfDataAsync();
File.WriteAllBytes("downloaded.pdf", pdfBytes);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 21:22:39