news 2026/5/10 12:17:48

浏览器书签工具一键导出AI对话为PDF/文本,支持ChatGPT/Claude/Gemini

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
浏览器书签工具一键导出AI对话为PDF/文本,支持ChatGPT/Claude/Gemini

1. 项目概述:一个浏览器书签,搞定所有主流AI对话导出

作为一名长期和各类AI助手打交道的博主,我深知一个痛点:和ChatGPT、Claude、Gemini这些工具聊了半天,产出了一堆有价值的代码、方案或者灵感,最后想整理归档或者分享给同事时,却异常麻烦。要么得一段段手动复制粘贴,格式全乱;要么想保存成PDF,却发现网页自带的“打印”功能会把侧边栏、导航栏这些无关内容全打进去,还得手动调整CSS,非常不优雅。

今天分享的这个叫“give-me/bookmarklets”的小工具,完美解决了这个问题。它本质上是一个浏览器书签工具,我习惯叫它“一键导出小助手”。你只需要把这个工具保存为浏览器书签,之后在任何支持的AI对话页面(目前完美支持ChatGPT、Claude、Gemini和Grok)点一下这个书签,就能把整段对话,连同可能存在的代码块、文件预览等“附加内容”,一键导出为干净的PDF格式清晰的纯文本文件。整个过程完全在本地浏览器中运行,不经过任何第三方服务器,你的对话数据百分百不会泄露。

它特别适合需要频繁整理AI对话内容的朋友,比如程序员存档技术讨论、学生保存学习记录、内容创作者收集灵感素材。接下来,我会详细拆解它的工作原理、手把手教你如何部署使用,并分享一些我深度使用后总结的独家技巧和避坑指南。

2. 核心原理与设计思路拆解

这个工具虽然用起来简单,但背后的设计思路非常巧妙,充分考虑了不同场景下的用户体验和安全性。它不是一个大而全的浏览器插件,而是一个轻量级的“书签小程序”,这个选择本身就很有讲究。

2.1 为何选择Bookmarklet而非浏览器插件?

首先,我们得明白Bookmarklet是什么。它是一段以javascript:开头的代码,保存在浏览器书签栏里。点击时,这段代码会在当前页面的上下文中执行。相比于浏览器插件,它有三大优势:

  1. 极致的轻量与便捷:无需安装,不占用浏览器后台资源,没有复杂的权限申请。就是一个书签,点一下就用。
  2. 绝对的安全与隐私:所有代码逻辑和数据处理都发生在你本地浏览器的内存中,执行完毕即消失。它不会像插件一样常驻后台,也无法访问你浏览器标签页之外的数据,从根本上杜绝了数据被上传到开发者服务器的风险。
  3. 无平台依赖与更新灵活:不受Chrome应用商店或Firefox插件中心的审核限制。一旦AI对话页面的HTML结构发生变化导致工具失效,开发者可以快速更新GitHub上的代码,用户只需替换书签中的URL即可更新,响应速度远快于插件审核上架。

当然,缺点也有,比如功能复杂度受限于单次执行的代码量,且无法进行复杂的后台交互。但对于“导出页面内容”这个单一、明确的需求,Bookmarklet是近乎完美的解决方案。

2.2 双引擎PDF导出策略的精妙之处

这个工具最核心的智慧体现在PDF导出上,它提供了“可搜索PDF”和“不可搜索PDF”两种模式,其底层采用了两种完全不同的技术方案,以适配不同AI平台的技术限制。

方案一:利用浏览器原生打印功能生成“可搜索PDF”这是默认且兼容性最好的方案。它的原理是:

  1. 工具通过CSS选择器,精准定位到网页中的对话主区域和可能的附加内容区域(如代码预览窗)。
  2. 在内存中创建一个临时的<div>容器,并将找到的所有内容克隆一份放入其中。
  3. 动态插入一段仅针对打印生效的CSS样式,其核心规则是:在打印时,隐藏页面上所有其他元素,只显示我们创建的那个临时容器。
  4. 调用浏览器的window.print()方法。此时,浏览器弹出的打印预览窗口里,就只有我们想要的纯净对话内容了。
  5. 用户选择“另存为PDF”,即可得到一个文本可被选中、搜索的PDF文件。之后,工具会自动清理掉临时创建的样式和容器。

这个方案的优点是生成的PDF质量高、文字可搜索、完全依赖浏览器自身能力,无需加载外部资源。但它的缺点是,生成的PDF样式(字体、布局)受限于浏览器打印引擎和用户打印设置。

方案二:引入html2pdf.js库生成“不可搜索PDF”这个方案主要作为备选,用于应对一些平台的安全策略。它的流程是:

  1. 当用户选择“生成不可搜索PDF”时,工具会从Cloudflare的公共CDN动态加载一个叫html2pdf.js的第三方开源库。
  2. 该库会在浏览器内,将我们找到的HTML内容先渲染到Canvas画布上,再将Canvas转换为PDF文件。
  3. 由于本质上是将文字变成了图片,所以生成的PDF内的文字无法被直接选中和搜索。

这个方案看似是退而求其次,实则解决了关键问题:内容安全策略。像ChatGPT这样的网站,可能会设置严格的CSP,禁止页面执行evalnew Function等,这有时会干扰方案一的打印流程。而方案二通过加载外部库,绕开了这些限制,保证了功能的可用性。开发者通过一个csp标志位来智能判断当前网站是否需要启用此方案,非常贴心。

2.3 内容定位机制:CSS选择器的艺术

工具能否准确抓取内容,完全依赖于其对目标网站HTML结构的理解,即那一串串的CSS选择器。例如,对于Claude,它用div[data-test-render-count]来找到对话容器,用div[data-testid="user-message"]来定位用户消息。这要求开发者必须持续跟进这些AI产品的界面更新。

注意:这是此类工具最脆弱的环节。一旦ChatGPT或Claude的前端工程师改了某个divclass名或>javascript:(function () { /* v. 0.12, github.com/give-me/bookmarklets */ let dialog, events = [], extras = [], csp = false; switch (location.hostname) { case 'claude.ai': dialog = document.querySelector('div[data-test-render-count]').parentElement; events = dialog.querySelectorAll('div[data-testid="user-message"], div[data-test-render-count]>div>div>div.font-claude-response'); extras.push(document.querySelector('div.h-full.top-0 div.font-mono')); extras.push(document.querySelector('div.h-full.top-0 div#wiggle-file-content')); extras.push(document.querySelector('div.h-full.top-0 div#markdown-artifact')); break; case 'chatgpt.com': dialog = document.querySelector('article').parentElement; events = dialog.querySelectorAll('div[data-message-author-role]'); extras.push(document.querySelector('section.popover>section')); csp = true; break; case 'grok.com': dialog = document.querySelector('div#last-reply-container').parentElement; events = dialog.querySelectorAll('div.message-bubble'); extras.push(document.querySelector('aside')); csp = true; break; case 'gemini.google.com': dialog = document.querySelector('#chat-history'); events = dialog.querySelectorAll('user-query-content, message-content'); extras.push(document.querySelector('code-immersive-panel>div.container')); extras.push(document.querySelector('deep-research-immersive-panel>div.container')); extras.push(document.querySelector('extended-response-panel response-container')); csp = true; break; default: return alert(location.hostname + ' is not supported'); } events = [...events].filter(Boolean); extras = [...extras].filter(Boolean); console.group(`Found elements at ${location.hostname}:`); console.debug('dialog', dialog); console.debug('events', events); console.debug('extras', extras); console.groupEnd(); let blocks = [dialog, ...extras]; let ts = new Date().toISOString().replace(/[-:T.]/g, '').slice(0, 14); if (confirm('Confirm if you prefer to export PDF instead of text')) { if (csp || confirm('Confirm if the PDF should be searchable')) { let temp = document.createElement('div'); temp.id = 'id-' + Math.random().toString(36).slice(2, 9); blocks.forEach(el => temp.appendChild(el.cloneNode(true))); let style = document.createElement('style'); style.textContent = `@media print{body>*{display:none!important}#${temp.id}{display:flex!important;flex-direction:column}}`; document.head.appendChild(style); document.body.appendChild(temp); print(); setTimeout(() => { document.head.removeChild(style); document.body.removeChild(temp); }, 1000); } else { let script = document.createElement('script'); script.src = 'https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.12.1/html2pdf.bundle.min.js'; script.onload = function () { let pdf = html2pdf().set({ margin: 5, filename: `${ts}.pdf`, html2canvas: {scale: 2, logging: false} }).from(blocks.shift()); blocks.forEach(el => pdf = pdf.toPdf().get('pdf').then(pdfObj => pdfObj.addPage()).from(el).toContainer().toCanvas().toPdf()); pdf.save(); }; document.body.appendChild(script); } } else { let txt = events.map((e, i) => `# ${i % 2 ? 'AI' : 'Me'}:\n\n${e.innerText.trim()}\n\n`).join(''); txt += extras.map((e, i) => `# Extra ${i + 1}:\n\n${e.innerText.trim()}\n\n`).join(''); let href = URL.createObjectURL(new Blob(['\uFEFF', txt], {type: 'text/plain;charset=utf-8'})); let link = Object.assign(document.createElement('a'), {href: href, download: `${ts}.txt`}); link.click(); URL.revokeObjectURL(link.href); } })();

  1. 保存:点击“保存”按钮。此时,你的书签栏里应该出现了一个以你刚才命名的新书签。

实操心得:建议将这个书签保存在书签栏的显眼位置,或者将其添加到浏览器工具栏(如果浏览器支持)。因为代码较长,在书签管理器里直接编辑容易出错,如果未来需要更新,更推荐的做法是删除旧书签,然后重新创建。

3.2 在不同AI平台上的使用流程

书签创建好后,使用就非常简单了,基本是“哪里需要点哪里”。

  1. 打开目标对话:首先,在浏览器中打开你想要导出的AI对话页面。确保页面已经完全加载完毕,对话历史滚动到了你需要的位置。
  2. 点击书签:点击你刚刚创建的那个书签。
  3. 跟随提示操作
    • 首先会弹出一个对话框,询问“Confirm if you prefer to export PDF instead of text”。意思是“确认是否要导出PDF而非文本”。点击“确定”则进入PDF导出流程,点击“取消”则直接导出为文本文件。
    • 如果选择导出文本:工具会立即生成一个.txt文件并触发下载。文件内容会清晰地用# Me:# AI:来区分对话角色,附加内容也会单独标注,格式非常整洁。
    • 如果选择导出PDF:会弹出第二个对话框,询问“Confirm if the PDF should be searchable”。意思是“确认PDF是否需要可搜索”。
      • 点击“确定”:工具会尝试使用方案一(浏览器打印)生成可搜索的PDF。此时会立即调起浏览器的打印预览窗口。你需要在这个打印窗口的“目标打印机”处,选择“另存为PDF”,然后点击保存。这是最关键的一步,很多新手会在这里愣住,以为出错了。
      • 点击“取消”:工具会使用方案二(html2pdf.js)生成不可搜索的PDF。这个过程可能需要几秒钟来加载库和生成文件,完成后会自动下载。

在不同平台上的细微差别

  • Claude.ai: 体验最流畅,通常直接使用可搜索PDF方案,且能很好地捕获侧边栏的代码文件等内容。
  • ChatGPT.com: 由于CSP限制,通常会触发不可搜索PDF方案。如果你在点击书签后没有立即弹出打印窗口,而是浏览器看起来“卡”了一下,稍等片刻就会开始下载PDF,这是正常现象。
  • Gemini.google.com: 行为与ChatGPT类似。
  • Grok.com: 根据其页面安全策略,也可能触发不可搜索PDF方案。

4. 高级技巧与深度定制解析

如果你不满足于基本使用,想更深入地掌控这个工具,或者解决一些特定问题,下面这些技巧会很有帮助。

4.1 理解并验证内容抓取

工具执行时,会在浏览器的开发者控制台输出调试信息。你可以按F12打开开发者工具,切换到Console标签页,然后再点击书签。你会看到类似这样的日志:

Found elements at chatgpt.com: dialog: <div>...</div> events: NodeList(20) [div, div, div, ...] extras: [section.popover>section]

这非常有用!events的数量代表了它找到了多少条对话消息。如果这里显示为0或数量远少于实际对话条数,说明CSS选择器可能已经失效,工具需要更新了。extras数组则显示了它找到了哪些额外的内容面板(比如上传的文件预览区)。

4.2 自定义文件名与导出内容

工具生成的PDF或文本文件,默认以时间戳命名,格式如20240415123045.pdf。如果你希望文件名能体现对话主题,可以在浏览器打印预览窗口(可搜索PDF方案)中手动修改“文件名”字段再保存。

对于文本导出,工具会导出它所能抓取到的所有对话历史。如果你只想导出部分内容,一个变通的方法是:先手动将网页滚动到你想要开始导出的那条消息附近,确保这些消息已经被加载到DOM中,然后再点击书签。不过,它无法智能地只导出“最后10条”或“选中部分”,这是Bookmarklet这种轻量级形式的局限。

4.3 处理导出PDF的样式问题

使用“可搜索PDF”方案时,最终的样式取决于你的浏览器打印设置。如果你对默认的PDF样式不满意(比如字体太小、背景色被打印出来),可以在打印预览窗口中进行调整:

  1. 布局:通常选择“纵向”即可。
  2. 纸张大小:A4是通用选择。
  3. 边距:可以选择“无”以获得最大内容区域,或者“最小值”。
  4. 选项务必勾选“背景图形”。如果不勾选,Claude、ChatGPT等深色背景下的文字可能会变成白底白字而无法显示。勾选后,才能正确打印出文字颜色。
  5. 缩放:保持100%即可。

这些设置会被浏览器记住,下次调用打印时一般会沿用,所以通常只需配置一次。

4.4 如何手动更新失效的书签

正如前面原理部分提到的,当AI网站改版,工具可能会失效。表现通常是点击书签后弹窗提示“xxx is not supported”或者导出的内容为空。

这时,你需要手动更新书签中的代码:

  1. 访问该工具的GitHub源码页面:https://github.com/give-me/bookmarklets/blob/main/bookmarklets/export.js
  2. 找到页面上最新的、完整的javascript:代码(通常以javascript:(function(){...})();的形式包裹)。
  3. 完全复制这段新代码。
  4. 回到浏览器书签管理器,找到原来的书签,编辑它,用新代码完全替换掉“网址”字段里的旧代码。
  5. 保存。这样就完成了更新。

个人经验:建议关注一下这个GitHub仓库,甚至可以点个Star。这样当工具失效时,你能第一时间想到可能是网站改版了,并知道去哪里获取更新。这是使用这类开源小工具的必备素养。

5. 常见问题排查与解决方案实录

在实际使用中,你可能会遇到一些问题。下面是我总结的一些常见情况及解决方法。

5.1 点击书签没有任何反应

这是最常见的问题,通常原因和解决方法如下:

问题现象可能原因解决方案
点击书签,页面毫无反应,无弹窗。1. 书签代码复制不完整,首尾缺失或中间有换行。
2. 浏览器安全策略禁止了书签栏执行大量JS代码。
1.重新复制粘贴:确保从javascript:开始,到最后的})();结束,完整且中间无换行。最好在纯文本编辑器里检查一遍。
2.尝试在地址栏执行:将书签代码完整复制,粘贴到浏览器的地址栏中,然后按回车。如果这时能运行,说明书签本身有问题,删除后重新创建。
地址栏执行后报语法错误。代码在传输过程中可能被意外修改(如邮件、聊天软件自动格式化)。始终从项目的官方GitHub页面或可信的文章中直接复制代码源。
仅在某些网站上无反应。该网站可能使用了严格的CSP,阻止了某些内联脚本执行方式。尝试使用“不可搜索PDF”选项(如果弹窗能出现的话)。或者,检查控制台是否有CSP报错。

5.2 导出内容不完整或错乱

问题现象可能原因解决方案
导出的PDF/文本只包含最近几条消息。AI聊天界面是“无限滚动”加载的,未滚动查看的历史消息并未被加载到DOM中。在点击书签前,手动向上滚动页面,直到所有你需要导出的历史对话都出现在屏幕上。确保它们被加载出来。
导出的文本中“Me”和“AI”角色标记错乱。工具通过消息在列表中的奇偶索引位置来判断角色,如果页面结构复杂,可能有干扰元素。检查控制台输出的events数量是否正确。如果错乱严重,可能是网站结构已大变,需等待工具更新。临时方案是导出后手动校对。
附加内容(如代码文件)没有被导出。该附加内容面板未被工具内置的CSS选择器捕获,或者面板处于隐藏/折叠状态。在点击书签前,确保相关的附加内容面板是展开可见的。例如,在Claude中点击了上传的文件,让预览窗显示出来。

5.3 PDF相关的问题

问题现象可能原因解决方案
选择“可搜索PDF”后,打印预览窗口内容空白。临时创建的容器样式可能未生效,或被页面更高优先级的样式覆盖。1. 在打印预览窗口的“更多设置”中,确认已勾选“背景图形”。
2. 尝试使用“不可搜索PDF”方案。
“不可搜索PDF”生成时间很长,或浏览器卡死。对话历史非常长,html2pdf.js在将大量HTML渲染到Canvas时消耗了大量资源。1. 耐心等待,长对话可能需要数十秒。
2. 考虑分批导出,或先导出为文本。
3. 检查控制台是否有JS错误。
PDF文件很大。“不可搜索PDF”本质是图片,分辨率高(scale: 2)会导致文件体积大。如果对文件大小敏感,优先使用“可搜索PDF”方案。对于不可搜索方案,可以尝试修改代码中的html2canvas: {scale: 2},将2改为1,但会降低清晰度。

5.4 浏览器兼容性与安全警告

问题现象说明与解决方案
在Safari上可能有限制。Safari对书签执行JS代码有时限制更严。确保在Safari的“偏好设置”->“高级”中,勾选了“在菜单栏中显示开发菜单”,然后在“开发”菜单中确保“允许JavaScript来自智能搜索字段”是启用的。
浏览器提示“此网页正在尝试加载不安全的脚本”。当使用“不可搜索PDF”方案时,会从Cloudflare CDN加载html2pdf.js库。浏览器可能会弹出警告。Cloudflare CDN是广泛使用的可信源,可以放心点击“加载”或“允许”。这是实现本地转换功能的必要步骤,代码本身不会外传你的数据。

这个工具是我目前用过最优雅、最轻量的AI对话导出方案。它把复杂的功能封装成了一个简单的书签,真正做到了“开箱即用,用完即走”。它的存在提醒我们,很多时候解决问题不需要重型的软件或插件,一段精心设计的脚本就能极大提升效率。当然,保持对工具更新机制的关注,理解其工作原理以应对偶尔的失效,是享受这种轻量化便利的同时,需要承担的一点小责任。如果你也经常需要整理和保存与AI的对话,强烈建议花五分钟设置一下,它会成为你浏览器里一个低调但无比实用的效率神器。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/10 12:16:49

程序超图:几何代数与空间计算的高效框架

1. 程序超图&#xff1a;几何代数与空间计算的革命性框架在异构计算和物理模拟领域&#xff0c;工程师们长期面临一个根本性挑战&#xff1a;如何将高层次的数学抽象&#xff08;如几何代数运算&#xff09;高效映射到底层硬件架构。传统编译技术基于二元边的程序语义图&#x…

作者头像 李华
网站建设 2026/5/10 12:15:37

从零构建C语言网络聊天室:核心架构与实战代码精讲

1. 为什么选择C语言实现网络聊天室&#xff1f; 用C语言写网络聊天室听起来像是用螺丝刀造汽车&#xff0c;但这恰恰是理解计算机通信本质的最佳方式。我十年前第一次用C实现聊天程序时&#xff0c;那种数据包在网线里真实流动的触感&#xff0c;是任何高级语言都无法给予的。 …

作者头像 李华
网站建设 2026/5/10 12:06:43

解锁AMD Ryzen隐藏性能:5分钟学会使用免费调试神器SMUDebugTool

解锁AMD Ryzen隐藏性能&#xff1a;5分钟学会使用免费调试神器SMUDebugTool 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: h…

作者头像 李华
网站建设 2026/5/10 12:03:58

九大网盘直链下载终极解决方案:告别限速困扰的技术革新

九大网盘直链下载终极解决方案&#xff1a;告别限速困扰的技术革新 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼…

作者头像 李华
网站建设 2026/5/10 12:03:07

面向企业级架构CMS 建站系统演进:技术底座剖析与现代化选型指南

导语与声明 在企业数字化转型的深水区&#xff0c;内容管理系统&#xff08;CMS/建站系统&#xff09;的选型直接关乎企业数字资产的安全与IT运维成本。本文涉及的架构分析仅代表个人工程技术观点&#xff0c;框架选型需结合企业自身业务场景、合规要求及团队技术栈进行综合评估…

作者头像 李华