讲师中心 微信公众号
AI工具推荐 视频效率加速

如何使用浏览器自动化技术抓取由 JavaScript 动态生成的 PDF 链接

秋雪大大_8538

秋雪大大_8538

发布时间:2026-02-08 13:00:02

|

694人浏览过

|

来源于php中文网

原创

如何使用浏览器自动化技术抓取由 JavaScript 动态生成的 PDF 链接

本文介绍为何传统 html 解析无法获取网页中由 javascript 动态渲染的 pdf 链接,并提供基于 f# 的浏览器自动化解决方案(canopy + chromedriver),实现可靠、可等待、可交互的 pdf 链接提取。

在爬取类似 https://www.kodis.cz/lines/region?tab=232-293 这类现代前端网站时,你可能会发现:无论使用 FSharp.Data.HtmlProvider、HtmlAgilityPack 还是 HttpClient 获取原始 HTML,都无法提取到 PDF 文件链接(如 https://kodis-files.s3.eu-central-1.amazonaws.com/...pdf)。根本原因在于:这些 <a href="...pdf"> 标签并非存在于服务端返回的初始 HTML 中,而是由 React 框架在浏览器中运行 JavaScript 后动态插入 DOM 的。

这意味着:

  • 服务端响应中 <div id="__next"> 内容为空或仅含占位符;
  • 所有 PDF 链接均由客户端 JS 异步加载(可能通过 API 请求后渲染);
  • 纯静态 HTML 解析器(包括 HtmlDocument.Load())只能看到“骨架”,看不到“血肉”。

✅ 正确解法:使用真实浏览器环境执行 JS,再提取渲染后的 DOM。

推荐方案:F# + Canopy 浏览器自动化

Canopy 是一个轻量、函数式风格的 F# 浏览器自动化库(底层基于 Selenium WebDriver),专为简洁、可读性强的 UI 测试与爬虫场景设计。

windows-shell
windows-shell

Windows 命令行编码与兼容规范。涵盖 GBK/UTF-8 编码、PowerShell/pwsh 互操作、Python/Node.js、Git 配置及代码生成规则。适用于 Windows 10/11 + MSYS2/Git Bash 环境下的所有命令行操作。

下载

立即学习“Java免费学习笔记(深入)”;

✅ 快速上手步骤

  1. 安装依赖(在 .fsx 脚本顶部):

    #r "nuget:canopy"
    #r "nuget:Selenium.WebDriver"
    #r "nuget:Selenium.WebDriver.ChromeDriver"
  2. 配置 ChromeDriver 路径(需提前下载匹配版本的 chromedriver.exe):

    open canopy
    open canopy.classic

canopy.configuration.chromeDir <- @"C:\path\to\your\chromedriver\" // Windows 示例 // Linux/macOS: "/usr/local/bin/chromedriver"

3. **启动浏览器并导航**:
```fsharp
start chrome
url "https://www.kodis.cz/lines/region?tab=232-293"
  1. 智能等待 + 提取 PDF 链接(关键!避免因加载延迟漏抓):
    // 定义就绪条件:至少出现 11 个 PDF 卡片(根据实际页面结构调整)
    let pdfCardsLoaded () = (elements ".Card_wrapper__ZQ5Fp").Length >= 11

compareTimeout <- 10.0 // 允许最长等待 10 秒 waitFor pdfCardsLoaded

// 提取所有含 PDF 的 href 属性 elements "a" |> List.filter (fun el -> let href = el.GetAttribute("href") System.String.IsNullOrEmpty(href) |> not && href.EndsWith(".pdf", System.StringComparison.OrdinalIgnoreCase)) |> List.iter (fun el -> let href = el.GetAttribute("href") printfn "PDF link: %s" href)

> ? 提示:若页面支持“加载更多”(如 “Další” 按钮),可模拟点击分页:
> ```fsharp
> click (elementWithText "button" "Další") // 或用更精确的选择器,如 "[data-testid='load-more']"
> waitFor (fun () -> (elements ".Card_wrapper__ZQ5Fp").Length >= 22)
> ```

#### ⚠️ 注意事项
- **务必设置 `waitFor`**:React 页面渲染有延迟,直接 `elements "a"` 可能返回空结果;
- **使用 `GetAttribute("href")` 而非 `InnerText()`**:PDF 链接常位于空 `<a>` 标签内(无文本内容),仅靠 `href` 属性存在;
- **PDF 判断建议用 `.EndsWith(".pdf", OrdinalIgnoreCase)`**:避免误判查询参数(如 `?file=report.pdf&t=123`);
- **生产环境请添加异常处理与资源清理**:
  ```fsharp
  try
    // ... 主逻辑
  finally
    quit() // 关闭浏览器

? 替代方案对比

方案 是否执行 JS 是否需浏览器 易用性 适用场景
HtmlAgilityPack / FSharp.Data ❌ ❌ ⭐⭐⭐⭐ 静态 HTML(服务端渲染 SSR)
Puppeteer Sharp (.NET) ✅ ✅ ⭐⭐⭐ 需精细控制(如拦截请求、截图)
Canopy ✅ ✅ ⭐⭐⭐⭐⭐ F# 项目首选:语法简洁、等待机制成熟、社区活跃
直接调用后端 API(如你已发现的 /api/schedules) N/A ❌ ⭐⭐⭐⭐⭐ 最优解(若接口稳定且无鉴权)——绕过渲染层,高效可靠
✅ 最佳实践建议:优先逆向分析网络请求(Chrome DevTools → Network → XHR/Fetch)。若发现 PDF 列表由 GET /api/documents?tab=232-293 返回 JSON,则直接调用该 API(配合 HttpClient + JWT/cookie 处理)比浏览器自动化更稳定、更快、更易维护。

总之,面对 JS 渲染的 PDF 链接,放弃“静态解析幻想”,拥抱“真实浏览器执行”——Canopy 让这一过程在 F# 中既强大又优雅。

热门AI工具

更多
Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

2175

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

3362

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

1136

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

3859

2025.09.10

chrome什么意思
chrome什么意思

chrome是浏览器的意思,由Google开发的网络浏览器,它在2008年首次发布,并迅速成为全球最受欢迎的浏览器之一。本专题为大家提供chrome相关的文章、下载、课程内容,供大家免费下载体验。

2766

2023.08.11

chrome无法加载插件怎么办
chrome无法加载插件怎么办

chrome无法加载插件可以通过检查插件是否已正确安装、禁用和启用插件、清除插件缓存、更新浏览器和插件、检查网络连接和尝试在隐身模式下加载插件方法解决。更多关于chrome相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

5479

2023.11.06

Chrome开启无痕模式
Chrome开启无痕模式

本专题整合了Chrome无痕模式开启相关内容,阅读专题下面的文章了解更多详细教程。

3907

2026.03.24

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6579

2023.08.02

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

20

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Valgrind支持平台说明
Valgrind支持平台说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn