简介:面向中文文献管理与 Zotero 深度使用者的 translators_CN 插件包,重点解决 CNKI 等中文学术站点题录难以被 Zotero 默认识别器正确解析的问题。包内共 31 个文件,以 21 个 JS 抓取脚本为核心,辅以 4 张 PNG 与 2 个 GIF 操作示意、JSON 数据、README、ESLint 配置及 1 份 PDF 参考文档,压缩包约 2.95MB,体量轻便,便于查阅脚本结构与扩展方式。已有 4988 人学习下载,说明其在中文文献抓取场景中具有较高关注度。读者可获得一套适用于 Zotero 的中文站点题录识别脚本集合,覆盖作者、年份、期刊、卷期、页码、DOI 与全文链接等字段的抓取思路,也可据此理解 translator 的匹配与解析逻辑,按需裁剪、增补站点规则,提升文献库构建与引用整理效率。
1. 中文文献抓取的老大难:为什么原版 Zotero 对知网“视而不见”
如果你用 Zotero 管文献,多半经历过这个场景:浏览器里打开知网详情页,点一下 Zotero 连接器图标,条目倒是进了文献库,可一看右侧信息栏——作者是空的、期刊名是空的、页码年份全都没有,只剩一个光秃秃的标题。手动补吧,一篇两篇还行,赶上写综述要导入上百篇,复制粘贴到怀疑人生。translators_CN 就是冲着这个痛点来的:它是一套面向中文文献数据库的 Zotero 翻译器集合,把知网、万方、维普等常见中文库的页面结构“翻译”成 Zotero 能读懂的元数据格式。适合正在用 Zotero 做中文文献管理的研究生、科研人员和需要批量整理论文的从业者。读完你会知道它改了什么、怎么装、怎么验证抓取有没有生效,以及几个我踩过的坑。
2. 从 translator 机制说起:translators_CN 到底动了哪块奶酪
2.1 Zotero 抓取网页的底层逻辑
Zotero 能在浏览器里一键抓文献,靠的是一组叫 translator 的脚本文件。每个 translator 本质上是一段 JavaScript,里面定义了“什么样的网页算目标页面”“从页面哪个 DOM 节点提取标题、作者、摘要”“数据怎么组装成 Zotero 条目”这几件事。浏览器连接器把当前页面 URL 发给 Zotero 客户端,Zotero 遍历本地 translators 目录,找到匹配当前域名的 translator 执行,拿到结构化数据后写进文献库。
原版 Zotero 自带一批英文数据库的 translator,比如 PubMed、arXiv、JSTOR 都有官方维护的脚本。中文库的情况比较尴尬:知网、万方的页面结构变动频繁,官方 translator 更新滞后,有时候能抓到标题却抓不到作者,有时候干脆一个字段都提取不出来。translators_CN 的做法是把这些中文库的 translator 单独拎出来维护,针对最新页面结构重写提取规则,再以插件或文件替换的方式装进 Zotero。它的价值不在于“多了一个功能按钮”,而在于把中文库的页面解析逻辑从“没人管”变成“有人持续修”。
常见做法是:translators_CN 的仓库里按数据库分目录存放.js文件,每个文件顶部有几行注释声明 translator 的 label、creator、target 正则和优先级。Zotero 加载时读这些元信息决定用哪个脚本。理解这一点很关键——后面排查抓取失败时,第一件事就是确认“当前页面有没有匹配到正确的 translator”。
2.2 translators_CN 的文件结构与版本匹配
translators_CN 仓库的目录结构不复杂,根目录下一般有几个关键文件:translators/存放各数据库的翻译器脚本,README说明安装方式和兼容版本。翻译器文件命名通常和数据库对应,比如CNKI.js、Wanfang.js这类。每个文件开头有一段类似下面的元数据声明:
{ "translatorID": "xxxx-xxxx-xxxx", "label": "CNKI", "creator": "translators_CN", "target": "^https?://(www\\.)?cnki\\.net/", "minVersion": "3.0", "maxVersion": "", "priority": 100, "inRepository": true, "translatorType": 4, "browserSupport": "gcsibv", "lastUpdated": "2024-xx-xx" }这段声明里,target是正则表达式,决定这个 translator 匹配哪些 URL;priority是优先级,数值越小越先被尝试;translatorType: 4表示网页抓取型翻译器;minVersion和maxVersion控制兼容的 Zotero 版本范围。translators_CN 需要和 Zotero 主版本对齐,Zotero 6 和 Zotero 7 的 translator API 有差异,装错版本会出现“脚本加载了但不执行”的玄学现象。
版本匹配这块,我一般按下面的对应关系来选:
| Zotero 版本 | translators_CN 分支/版本 | 安装方式 | 注意事项 |
|---|---|---|---|
| Zotero 6.x | 对应 6.x 兼容版 | 插件安装或手动替换 | 部分新版脚本用了 Zotero 7 的 API,装上不生效 |
| Zotero 7.x | 对应 7.x 版本 | 手动放入 translators 目录 | 目录路径与 6.x 不同,别放错位置 |
| 不确定版本 | 看仓库 README 的兼容说明 | 先备份原 translators 目录 | 替换前务必备份,方便回滚 |
提示:Zotero 7 的 translators 目录不在安装目录下,而在用户数据目录里。Windows 一般是
C:\Users\<用户名>\Zotero\translators\,macOS 是~/Zotero/translators/。往安装目录里塞文件是常见错误,放进去不会报错,但就是不生效。
2.3 手动安装:把文件放到正确的位置
translators_CN 的安装方式分两种:插件形式安装和手动替换 translators 目录。插件形式适合不熟悉文件系统的用户,但更新频率依赖打包;手动替换更直接,也方便单独替换某个数据库的脚本。我一般推荐手动方式,因为排查问题时能精确控制哪个文件生效。
先确认 Zotero 的数据目录位置,在 Zotero 里点“编辑 → 设置 → 高级 → 文件和文件夹”,能看到“数据目录”路径。translators 子目录就在数据目录下面。操作步骤:
# 1. 先备份原有 translators 目录,给自己留后悔药 cp -r ~/Zotero/translators ~/Zotero/translators_backup_$(date +%Y%m%d) # 2. 从 translators_CN 仓库下载翻译器文件 # 假设下载到 ~/Downloads/translators_CN/translators/ # 3. 把需要的 .js 文件复制进 Zotero translators 目录 # 建议先只替换目标数据库的脚本,不要一次全量覆盖 cp ~/Downloads/translators_CN/translators/CNKI.js ~/Zotero/translators/ cp ~/Downloads/translators_CN/translators/Wanfang.js ~/Zotero/translators/ # 4. 重启 Zotero,让 translator 重新加载上面命令里,第一步的备份是血泪经验——曾经有一次全量覆盖后,连英文数据库都抓不了,因为新旧脚本冲突,最后靠备份才回滚回来。第三步只替换目标脚本,是为了把影响面控制在单个数据库上。第四步重启不能省,Zotero 启动时才会扫描 translators 目录,不重启的话新脚本不会加载。
如果你用的是插件安装方式,在 Zotero 里点“工具 → 插件”,把 translators_CN 的.xpi文件拖进去,重启即可。插件方式的好处是可以在插件列表里看到版本号,方便判断是否需要更新;坏处是有些翻译器文件不会随插件自动更新,还是得手动替换。
装完之后怎么确认生效?打开 Zotero,点“编辑 → 首选项 → 高级 → 设置编辑器”,搜索translators相关配置,或者更直接的办法:在浏览器打开一个知网详情页,点 Zotero 连接器,看抓下来的条目字段是否完整。如果标题有、作者和期刊名也有,说明 translator 在工作;如果只有标题,说明页面匹配到了但字段提取规则没跑通,需要进下一章的排查流程。
3. 知网、万方、维普:translators_CN 的实战抓取流程
3.1 单篇抓取与批量导入的操作差异
单篇抓取是最基础的使用场景。浏览器装好 Zotero Connector 后,打开目标文献的详情页,点击浏览器右上角的 Zotero 图标,客户端会弹出“正在保存”的提示,几秒后条目出现在指定分类下。translators_CN 生效时,抓下来的条目应该包含标题、作者、期刊/会议名、年份、卷期、页码、DOI 和摘要这些字段。如果摘要抓不到,通常是页面里摘要区域的 CSS 选择器变了,需要手动更新 translator 里的提取规则。
批量导入的做法略有不同。知网的结果列表页支持勾选多篇后“导出/参考文献”,但这种方式导出的是格式化的文本,不是元数据。translators_CN 更适合在检索结果页逐条点开详情页抓取,或者用 Zotero 的“保存到 Zotero”批量模式——在结果列表页点击连接器图标,Zotero 会尝试识别列表里的多条记录,逐条创建条目。这个功能依赖 translator 对列表页结构的支持,translators_CN 里部分脚本实现了列表页解析,但不是所有数据库都支持。
我一般这样操作批量导入:
// 伪代码示意 translator 中列表页解析的核心逻辑 // 实际文件里是完整的 JS 函数,这里只展示字段映射关系 function parseListPage(doc) { // 选中结果列表里每一条记录的容器 var rows = doc.querySelectorAll('.result-table-list tbody tr'); var items = []; rows.forEach(function (row) { var item = {}; // 标题:从标题链接里取文本 item.title = row.querySelector('.name a').textContent.trim(); // 作者:多个作者用分号分隔 item.creators = row.querySelector('.author').textContent.split(';'); // 期刊名和年份:从来源列拆出来 item.publicationTitle = row.querySelector('.source').textContent.trim(); // 详情页链接,用于后续补全摘要等字段 item.url = row.querySelector('.name a').href; items.push(item); }); return items; }这段逻辑说明的是 translator 在列表页怎么定位每条记录、从哪个 DOM 节点取字段。querySelectorAll的选择器就是最容易失效的部分——数据库前端一改版,类名从.result-table-list换成别的,解析就断了。参数上,item.creators需要按 Zotero 要求的格式组装成对象数组,只传字符串数组的话作者字段会显示异常,这是新手常犯的错误。
3.2 中文库页面结构的适配差异
不同中文数据库的页面结构差异很大,translators_CN 为每个库单独维护脚本,不能混用。知网的详情页信息集中在页面顶部的表格区域,作者、机构、期刊名都有明确的 DOM 结构,提取相对稳定;万方的详情页字段分散在多个区块,有些字段用 JavaScript 动态渲染,translator 执行时可能还没加载完,需要加延时或监听 DOM 变化;维普的页面结构变动频率较高,translator 的维护压力也最大。
适配差异还体现在字段命名上。知网的“来源”字段可能是期刊名,也可能是学位授予单位,translator 需要根据文献类型判断映射到publicationTitle还是university。万方的“作者单位”字段和“作者”字段分开存放,组装creators时要按顺序对应。这些细节在 translator 脚本里都有体现,读脚本时留意itemType的分支判断就能看懂。
实际使用中,我建议按数据库分别验证:先用知网抓一篇典型期刊论文,确认字段完整;再用万方抓一篇学位论文,确认university和thesisType字段有没有正确填充;最后用维普抓一篇会议论文,检查conferenceName和proceedingsTitle。三个库都跑通,说明 translators_CN 的安装和版本匹配基本没问题。
3.3 元数据补全与 PDF 链接处理
抓取只是第一步,元数据补全和 PDF 附件处理是后续容易出问题的环节。translators_CN 的脚本里通常会尝试抓取 PDF 下载链接,但中文库的 PDF 链接往往需要登录态或机构权限,translator 拿到的链接可能是相对路径或带时效参数的临时地址。抓下来的附件如果打不开,先看 Zotero 条目右侧的附件列表,链接是灰色还是可点击——灰色说明链接失效,需要在浏览器里手动下载 PDF 后拖进 Zotero 条目。
元数据补全还有一个场景:从知网抓下来的条目缺摘要。这是因为摘要区域在页面里是异步加载的,translator 执行时 DOM 还没渲染出来。解决办法是在 translator 里加一个延时等待,或者抓完后用 Zotero 的“更新元数据”功能重新拉取。我一般会在抓取后抽查几条,看abstractNote字段是否有内容,空的就手动补或者换用详情页单独抓取。
// translator 中等待异步内容加载的常见写法 // 用 setTimeout 延迟提取,或者监听 DOMContentLoaded 后再执行 function fetchWithDelay(doc, selector, delay) { return new Promise(function (resolve) { setTimeout(function () { var el = doc.querySelector(selector); // 取不到就返回空字符串,避免整个抓取流程中断 resolve(el ? el.textContent.trim() : ''); }, delay); }); }这段代码展示的是延时提取的思路,delay参数一般设 500 到 1500 毫秒,太短没加载完,太长拖慢抓取速度。实际 translator 里不会到处用延时,而是结合MutationObserver监听节点变化,效率更高。参数上,selector要写具体到摘要容器的选择器,写得泛了容易抓到错误的文本。
4. 抓取失败排查:五类高频翻车场景与修复路径
4.1 翻译器版本与 Zotero 版本错位
现象:translators_CN 文件已经放进 translators 目录,重启 Zotero 后抓取知网页面,连接器图标显示“正在保存”,但条目创建后只有 URL 和标题,作者、期刊全空,或者直接提示“无法保存此条目”。
原因:最常见的是 Zotero 主版本和 translator 版本不匹配。Zotero 7 改了 translator 的 API,部分旧版脚本用了已废弃的方法,加载时不报错但执行到一半静默失败。另一种情况是 translator 文件里的maxVersion限制导致 Zotero 拒绝加载——文件放进去了,但 Zotero 认为“这个脚本不支持当前版本”,直接跳过。
解决:先确认 Zotero 版本号(帮助 → 关于 Zotero),再对照 translators_CN 仓库 README 的兼容说明选对应分支。如果版本对但还不生效,打开 Zotero 的调试日志(帮助 → 调试输出日志),再抓一次页面,看日志里有没有Translator failed或No translators found的字样。日志里会打印当前尝试了哪些 translator、匹配到了哪个、在哪一步抛错。根据报错位置回去改脚本的minVersion/maxVersion,或者换用兼容版本的文件。
4.2 数据库页面改版导致抓取为空
现象:之前用得好好的,某天突然抓取同一数据库的页面,字段大面积缺失,标题能抓到但作者、摘要全空,换几篇文献都一样。
原因:数据库前端改版,DOM 结构变了,translator 里的 CSS 选择器对不上。中文库改版频率不低,尤其是知网和维普,类名调整、区块位置挪动都发生过。translator 的提取规则是硬编码选择器的,页面一改就断。
解决:在浏览器里打开目标页面,按 F12 打开开发者工具,用元素选择器查看标题、作者、摘要对应的实际 DOM 结构和类名,和 translator 脚本里的querySelector对比,把过时的选择器替换成新的。改完保存文件,重启 Zotero 再测。如果改起来费劲,可以去 translators_CN 仓库提 issue 或看有没有人已经提交了更新版本。临时方案是把页面 URL 和抓取结果整理出来,手动建条目,等脚本更新后再补。
4.3 附件与 PDF 链接失效
现象:条目元数据抓下来了,但附件列表里的 PDF 链接是灰色的,点开提示 404 或要求登录;或者附件根本没被创建,只有条目没有文件。
原因:中文库的 PDF 下载链接通常带时效签名或依赖登录态,translator 抓到的链接是临时地址,过几小时就失效。另外有些库的 PDF 链接藏在 JavaScript 事件里,不是标准的href,translator 按常规方式提取拿不到。
解决:不要依赖 translator 自动抓 PDF,尤其是需要机构权限的库。我的习惯是条目抓完后,在浏览器里手动下载 PDF,再拖到 Zotero 对应条目上作为附件。如果要批量处理,可以写一个脚本读取 Zotero 条目的 URL 字段,用命令行工具批量下载能公开访问的 PDF,再通过 Zotero 的“附件 → 添加附件”批量关联。注意别用来源不明的下载工具,避免把登录态泄露出去。
4.4 重复导入与条目合并
现象:同一篇文献抓了两次,文献库里出现两条记录,字段略有差异;或者从不同数据库抓同一篇论文,条目重复但作者列表格式不一样。
原因:Zotero 的去重依赖 DOI、标题和作者组合判断,中文库的 DOI 字段经常缺失或格式不统一,标题里的全角半角符号、空格差异也会导致判重失败。translators_CN 抓下来的条目如果没有 DOI,重复导入就很难自动合并。
解决:抓取前先在 Zotero 里按标题搜索确认没有重复;抓完后用“重复条目”功能手动合并(在文献库根目录右键 → 重复条目)。合并时注意保留字段更完整的那条,作者列表选格式正确的。长期方案是在 translator 里尽量提取 DOI 并写入DOI字段,有了 DOI 之后判重准确率会高很多。我一般会在批量导入后跑一遍重复条目检查,把合并后的条目统一整理分类,避免后期引用时选错。
4.5 网络环境与代理配置干扰
现象:浏览器能正常打开数据库页面,但 Zotero 连接器抓取时报网络错误,或者抓下来的条目缺少需要额外请求才能拿到的字段(比如摘要需要二次请求详情接口)。
原因:Zotero 客户端的网络请求和浏览器的网络环境可能不一致。浏览器走了代理或专线,Zotero 客户端没走,导致 translator 里发起的二次请求失败。另一种情况是数据库对频繁请求做了限制,批量抓取时触发风控,后续请求被拒绝。
解决:检查 Zotero 的代理设置(编辑 → 设置 → 高级 → 网络),确认和浏览器环境一致。批量抓取时控制节奏,不要短时间连续抓几十篇,中间留几秒间隔。如果 translator 里有二次请求逻辑,可以在脚本里加请求间隔和失败重试。遇到持续网络错误,先单独用浏览器验证页面可访问,再排查 Zotero 侧配置,别一上来就怀疑 translator 脚本有问题。
5. 验证 translator 是否真正生效:日志、版本锁定与一个笨办法
装完 translators_CN 最怕的是“看起来装了,实际没跑”。我一般用三层验证:第一层看抓取结果字段是否完整,第二层看 Zotero 调试日志里 translator 的执行记录,第三层用版本锁定防止自动更新把可用版本覆盖掉。
调试日志的用法:Zotero 菜单“帮助 → 调试输出日志”,勾选后抓一次页面,日志窗口里会打印类似(3)(+0000001): Translate: CNKI的行,后面跟着字段提取的详细过程。如果看到Translate: CNKI但后面报Item type not supported,说明 translator 匹配到了但itemType映射有问题;如果连Translate:行都没有,说明页面 URL 没匹配上target正则,得回去检查正则表达式。
版本锁定是我踩坑之后养成的习惯。translators_CN 更新频繁,有时候新版本脚本在旧页面上反而抓不全,自动更新会把能用的版本覆盖掉。做法很简单:把当前可用的 translators 目录整体备份一份,Zotero 设置里关掉 translator 自动更新(如果有的话),每次升级前先在备份环境里测一遍。下面这个命令用来快速对比新旧脚本差异,确认更新只改了预期部分:
# 对比备份目录和新版本 translators 的差异 diff -rq ~/Zotero/translators_backup_20240101 ~/Zotero/translators # 只看某个数据库脚本的具体改动 diff ~/Zotero/translators_backup_20240101/CNKI.js ~/Zotero/translators/CNKI.js第一条命令列出哪些文件有变动,第二条看单个文件的具体差异。参数上,-r递归比较子目录,-q只输出有差异的文件名,不打印具体内容。看差异时重点关注target正则、querySelector选择器和itemType分支,这三处变了就说明提取逻辑有调整,需要重新验证抓取结果。
还有一个笨但有效的验证方法:建一个空的测试分类,专门用来抓取测试条目,每次更新 translator 后先抓三篇不同类型的文献(期刊论文、学位论文、会议论文),确认字段完整再清理掉。这个习惯帮我省了很多事后补元数据的时间。从那以后我每次换 Zotero 版本或更新 translators_CN,都强制走一遍“备份 → 替换 → 三篇测试 → 看日志”的流程,再批量导入正式文献。希望帮到你。
本文还有配套的精品资源,点击获取