客户端JS提取在线PDF内容的Tampermonkey/Greasemonkey适配问题
在线PDF特征提取用户脚本实现方案
核心需求
- 基于Tampermonkey/Greasemonkey用户脚本实现,适配Firefox或Chrome浏览器即可,支持提取在线PDF内符合指定正则规则的文本内容
- 已验证基础逻辑有效性:在Firefox内置pdf.js查看器打开的PDF页面,控制台手动执行以下代码可正常完成匹配:
var matchList = document.body.innerText.match(/my_regex/gi);
- 现存待解决问题:
- 初版Greasemonkey脚本无法在Firefox的PDF直链页面正常加载执行
- Chrome默认PDF查看器通过embed插件加载内容,仅能获取到src为
about:blank的embed占位元素,无法直接读取PDF文本 - 尝试自行拉取PDF资源、引入JS解析库处理的路径暂未跑通,不确定可行性,也不确定是否必须开发独立浏览器扩展才能实现需求
分浏览器适配方案
Firefox 端适配
原脚本无法运行的核心原因有两点:一是@include *.pdf的匹配规则未覆盖带参数的PDF链接、也未匹配Firefox内置pdf.js查看器的特殊上下文;二是脚本默认执行时机过早,此时pdf.js还未将PDF文本渲染到DOM树中。
修正后的脚本头配置如下:
// ==UserScript== // @name MyExtractor // @version 1 // @grant none // @match *://*/*.pdf // @match *://*/*.pdf?* // @run-at document-idle // ==/UserScript==
逻辑部分不要直接在脚本初始化时读取DOM内容,增加渲染完成判断,等pdf.js把文本层加载完毕再执行匹配,参考代码:
const checkRender = setInterval(() => { const pdfText = document.body.innerText?.trim(); // 文本长度超过阈值即判定PDF内容渲染完成 if (pdfText && pdfText.length > 100) { clearInterval(checkRender); const matchList = pdfText.match(/my_regex/gi); console.log('正则匹配结果:', matchList); alert('提取完成,结果已输出至控制台'); } }, 500);
稳定性提示:Greasemonkey 4+版本对特殊内容类型页面的沙箱限制较严,换成Tampermonkey运行脚本兼容性更好。
Chrome 端适配
Chrome默认使用自研PPAPI插件加载PDF,所有PDF内容都在插件进程内渲染,不会暴露给页面DOM,那个src为about:blank的embed标签只是插件的占位容器,没有任何内容读取接口,直接操作DOM不可能拿到PDF文本。
两种可选实现路径:
- 将Chrome默认PDF查看器替换为基于pdf.js实现的第三方查看器扩展,之后逻辑与Firefox端完全一致,直接读取渲染后的DOM文本即可
- 采用下文的通用跨浏览器方案,不依赖浏览器内置PDF查看器实现
通用跨浏览器实现方案
该方案不需要依赖浏览器自带的PDF渲染逻辑,脚本自行拉取PDF资源、通过纯JS库解析提取文本,适配所有Chromium内核和Firefox浏览器,稳定性更高,不需要开发独立浏览器扩展,用户脚本权限完全可以覆盖需求。
实现逻辑
- 脚本通过
@require配置直接引入预构建好的pdf.js解析库,不需要手动处理依赖加载问题 - 自动识别PDF资源地址:如果当前页面URL以.pdf结尾,直接使用当前地址;如果是普通网页,遍历页面内所有链接,提取指向PDF资源的地址
- 拉取PDF资源的二进制数据,传入pdf.js逐页提取文本,拼接完成后执行正则匹配
避坑说明
- 跨域问题:如果PDF资源与当前页面不同源,给脚本添加
@connect *权限(Tampermonkey原生支持)即可绕过普通页面的跨域限制拉取资源 - 之前引入解析库失败基本是因为未正确配置
@require路径,或是没有处理pdf.js的Worker依赖,直接使用预构建的单文件版本pdf.js即可避开这类配置问题
内容的提问来源于stack exchange,提问作者Brett
相关产品推荐
相关产品推荐

