CSDN 文章完美打印:一键展开代码段、去除运行卡片与广告干扰

发布时间:2026/10/5 10:44:18
CSDN 文章完美打印:一键展开代码段、去除运行卡片与广告干扰 前几天在 CSDN 刷到一篇不错的底层原理笔记想把正文打出来带去例会。按下 CtrlP 那一刻我心里已经有数了代码段没展开、页面顶部拖着导航、右侧塞着推荐、正文中间还插着一块“该文章已生成可运行项目”的卡片。打印预览拉到第三页全是广告和侧栏真正有用的内容被压缩得歪歪扭扭。这种经历大家应该都有。CSDN 文章页为了浏览体验塞了一堆互动组件但打印输出时这些都是累赘。我后来花小半天时间把路子趟顺了在开发者工具里展开代码段、用 CSS 干掉干扰卡片、配合浏览器打印设置的几个关键开关最终能稳定产出干净得像白纸一样的打印稿或 PDF。下面把这套方案完整写清楚核心就是三件事CSDN 网页完美打印、展开代码段、去除“该文章已生成可运行项目”这类多余提示。这不光是 CSDN 能用换到掘金、博客园、甚至公众号文章页思路完全一致。如果你也经常打印技术文章做纸质参考这篇应该能帮你省下不少纸和墨。1. 先拆清楚CSDN 页面打印时这些干扰分别藏在哪1.1 代码段折叠不是浏览器不打印是页面组件没展开打印网页时浏览器只会把当前 DOM 里可见的内容输出到纸张。这个“可见”指的是 CSS 渲染后的状态而不是你屏幕上看到的那个样子。CSS 里 display:none 的元素不会打出来JS 控制的折叠容器如果没展开它的完整内容同样不会出现在纸面上。CSDN 有些代码块看起来是“收起来”的就是因为在文章加载时页面脚本给代码容器设置了最大高度或 overflow 隐藏。用户需要点击“展开”按钮JS 再把它撑开。CSDN 文章页的情况分两种。一种是普通 Markdown 代码块默认完整展开打印正常。另一种是接入了增强组件的文章代码段被塞进一个折叠组件里页面上只露出第一行或者一个“展开阅读”入口。这种组件通常会渲染一个按钮点击后容器高度从固定值改为 auto。问题在于浏览器打印时不会帮你点击这个按钮。你可以直接 CtrlP把预览拉到代码块附近——十有八九只能看到一截。所以处理的第一件事就是让所有折叠容器先展开。手动一个个点也不是不行但一篇文章动辄五六个代码块多了真的很烦。不如直接在控制台跑一段 JS遍历所有按钮逐个触发 click几秒钟搞定。这就像你要打开一屋子抽屉不需要一个个手拉直接拿一把遥控器把所有开关按一遍。1.2 “该文章已生成可运行项目”卡片一个典型的页面包袱这个卡片最近在 CSDN 文章里出现频率很高。它通常出现在包含完整代码的文章中长成一个小方块写着“该文章已生成可运行项目”旁边带一个“一键运行”按钮目的是把用户引流到 CSDN 的在线代码运行环境。对在线阅读来说它是个入口但对打印来说它就是个纯商业化的版面杀手。一张 A4 纸竖着打它自己就能占掉三分之一到一半的空间尤其当它出现在正文中间时还会把代码段的连续阅读打断。这个卡片不一定有稳定的 class 名因为 CSDN 前端迭代过好几次。所以我在处理时优先用文本匹配遍历正文容器里所有元素找到文本包含“已生成可运行项目”的节点直接把它的父级卡片隐藏掉。这个方法比写死 class 选择器稳得多类名改了也能命中。1.3 一颗完整的“干扰清单”打印前需要清理什么除了代码段和运行项目卡片CSDN 的文章页还有其他一堆打印时没用的元素。我整理了一份常用清单做成了表格。这里的元素命名是我实际见到的常见形式假如你的浏览器里名字不同按定位逻辑去处理就好。干扰内容通常的位置处理建议顶部导航栏固定顶部display:none右侧侧边栏文章主体右侧display:none面包屑导航正文上方display:none作者信息卡片标题下方display:none点赞、收藏、分享栏正文上下或悬浮display:none相关文章推荐正文末尾display:none评论区正文末尾之后display:none二维码/关注公众号文末或悬浮display:none这些东西在打印稿里没有信息增量。删除的方式不是动用鼠标而是注入一段 CSS把所有干扰容器统一隐藏。这样做的好处是正文的排版会自然重新填满页面不会留下难看的空白。2. 半小时快排方案开发者工具里展开代码段隐藏干扰元素先说清楚这是“一次性使用”方案适合偶尔打印。打开文章页F12粘贴脚本CtrlP。全程两分钟不用装任何东西。如果你需要经常打印可以看第三节的油猴自动化方案。2.1 自动展开全部代码段的控制台脚本先在 Console 里执行这段 JS(function expandAll() { var list document.querySelectorAll(button, div, span); var count 0; list.forEach(function(node) { var text node.textContent || ; if (/展开(全部|代码|阅读|查看)/.test(text) text.length 20) { node.click(); count; } }); console.log(已点击 count 个展开按钮); })();原理很简单把所有可能承担“展开”职责的元素拿下来检查其文本内容是否包含“展开代码”“展开阅读”“展开全部”等常见关键词。匹配成功就触发 click。之所以写成遍历所有按钮而不是只找固定 class还是为了对抗 CSDN 的类名变化。文本匹配虽然看起来很粗暴但在真实页面上命中率最高。执行完你可以立刻按 CtrlP把预览翻到代码段位置看看。如果代码已经完整露出来说明展开成功如果还是折叠状态说明触发按钮的关键词不在这几个词里面。那就手动点一次然后在控制台的 Elements 面板里看那个按钮长什么样把关键词补进正则。这个方法我再没遇到漏网的情况。2.2 用注入 CSS 的方式隐藏干扰元素隐藏干扰元素我一般不直接用浏览器自带的打印“简化页面”因为那个功能会连带删掉正文的代码高亮和预格式文本得不偿失。我选择在 Console 里动态插入一个 style 标签专门针对打印场景加样式。(function hidePageClutter() { var s document.createElement(style); s.innerHTML media print { #csdn-toolbar, aside, .toolbox, .blog-footer, .recommend-box, .article-info-box, .breadcrumb, .comment-box, .markdown_views .blog_admin, .pulllog-box { display: none !important; } .main-content, .article_content, .container { width: 100% !important; margin: 0 !important; } } ; document.head.appendChild(s); })();注意我用了 media print 包起来这样屏幕上的页面布局不受任何影响只有打印时这些规则才生效。你可能会问为什么不直接 display:none因为如果直接在屏幕上隐藏这些元素打印预览倒是干净了但你在浏览器里正常浏览文章时也会缺胳膊少腿那体验太糟糕了。用 media print 包裹屏幕和打印互不干扰。class 的选择器列表我这里列了常见项具体页面上如果还有残余就在 Elements 面板里把多余的元素选中右键选择“删除元素”或者往这个列表里追加它的选择器即可。2.3 补充打印专用的正文字体与代码样式CSDN 在线阅读的排版是为屏幕设计的字距、行高、代码块的背景色在打印时都不一定合适。我一般会在上面的 style 标签里再追加一段代码块打印样式media print { .article_content { font-size: 11pt; line-height: 1.7; } .article_content pre { white-space: pre-wrap; word-break: break-all; border: 1px solid #d0d7de; background: #f6f8fa; padding: 12px; border-radius: 4px; font-size: 9pt; font-family: Cascadia Code, Consolas, Monaco, Courier New, monospace; page-break-inside: avoid; } .article_content p { orphans: 2; widows: 2; } h1, h2, h3, h4 { page-break-after: avoid; } }关键是 white-space: pre-wrap 和 word-break: break-all。代码块原本可能是横向滚动的现在改成换行长代码就不会超出纸面边界。page-break-inside: avoid 能让一个代码块尽量保持在同页内不会被拦腰截断。这里给 pre 加了浅灰背景和边框是为了配合打印对话框里的“背景图形”开关使用下文第四节会专门说这个开关。2.4 整套流程的实测步骤与注意点把上面两步合起来实际操作顺序是这样的打开文章页按 F12 进入开发者工具切到 Console。粘贴展开脚本回车看控制台输出“已点击 X 个展开按钮”。粘贴隐藏脚本回车。按 CtrlP 进入打印预览检查第一页到最后一页是否还有广告、卡片、或者折叠代码。在打印预览右侧选择“更多设置”勾选“背景图形”调整边距然后另存为 PDF 或直接打印。有几个实际经验值得记一下。一是文章如果特别长CSDN 有懒加载机制某些代码块要滚动到附近才渲染出来。遇到这种情况展开前先用 PageDown 快速滚几圈或者执行 window.scrollTo(0, document.body.scrollHeight) 再滚回来让所有代码块全部渲染完然后再跑展开脚本。否则脚本只处理了已渲染的部分。二是执行完脚本之后别急着打印先在预览里滑动看一遍确认没有出现“展开按钮虽然点了但代码还是只显示到一半”的问题。真碰上这种问题多半是文章同时用了多个组件展开事件有依赖重新执行一两次脚本基本就能解决。提示脚本里的选择器和关键词是基于当前 CSDN 页面的常见结构写的如果遇到失效先在 Elements 面板里确认实际 class 名再调整选择器。3. 一劳永逸油猴脚本把“完美打印”变成页面上一个按钮3.1 为什么用油猴而不是更“正规”的浏览器插件这一节写给需要天天打技术文章、或者经常给团队攒资料库的朋友。手动方案每篇文章都要开控制台粘贴两段代码用多了确实烦。油猴脚本Tampermonkey的好处是它仍然是个浏览器插件但脚本可以精确地只在 CSDN 文章页运行时生效打开文章就自动完成展开和隐藏再往页面角落挂一个“清洁打印”按钮点一下直接出打印预览。成本极低效果稳定。当然也可以去写一个正经的浏览器扩展但那样要维护 manifest、图标、商店上架流程为了一个打印功能不值当。油猴脚本本身支持 match 白名单运行时不污染其他站点代码又全部开源随时能改适合个人工具这种量级。3.2 脚本源码与逐段解释// UserScript // name CSDN 清洁打印助手 // namespace local.csdn.cprint // version 1.0.0 // description 展开 CSDN 代码段、隐藏干扰卡片、一键打印 // match https://blog.csdn.net/*/article/details/* // grant none // run-at document-idle // /UserScript (function() { use strict; function expandAllCodeBlocks() { var nodes document.querySelectorAll(button, div, span); var count 0; nodes.forEach(function(node) { var text node.textContent || ; if (/展开(全部|代码|阅读|查看)/.test(text) text.length 20) { node.click(); count; } }); console.log([CSDN Clean Print] 展开按钮点击数 count); } function injectPrintStyle() { if (document.getElementById(csdn-clean-print-style)) return; var style document.createElement(style); style.id csdn-clean-print-style; style.innerHTML media print { #csdn-toolbar, aside, .toolbox, .blog-footer, .recommend-box, .comment-box, .breadcrumb, .article-info-box { display: none !important; } .main-content, .article_content, .container { width: 100% !important; margin: 0 !important; } .article_content { font-size: 11pt !important; line-height: 1.7 !important; } .article_content pre { white-space: pre-wrap !important; word-break: break-all !important; border: 1px solid #d0d7de !important; background: #f6f8fa !important; padding: 12px !important; border-radius: 4px !important; font-size: 9pt !important; page-break-inside: avoid !important; } h1, h2, h3, h4 { page-break-after: avoid !important; } } ; document.head.appendChild(style); } function hideRunProjectCard() { var all document.querySelectorAll(#content_views div, .article_content div); all.forEach(function(el) { if (!el.querySelector(div) /已生成可运行项目/.test(el.textContent || )) { var parent el.closest(div[class], div[id]); if (parent) parent.style.display none; else el.style.display none; } }); } function cleanPrint() { expandAllCodeBlocks(); hideRunProjectCard(); injectPrintStyle(); setTimeout(function() { window.print(); }, 800); } function addPrintButton() { var btn document.createElement(button); btn.id csdn-clean-print-btn; btn.textContent 清洁打印; btn.style.cssText position:fixed;right:20px;bottom:120px;z-index:99999;padding:8px 16px;font-size:14px;background:#057748;color:#fff;border:none;border-radius:6px;cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,.2); btn.addEventListener(click, cleanPrint); document.body.appendChild(btn); } function runWhenReady() { expandAllCodeBlocks(); hideRunProjectCard(); injectPrintStyle(); addPrintButton(); // 监听页面动态变化自动处理后续加载的代码段 var observer new MutationObserver(function() { expandAllCodeBlocks(); hideRunProjectCard(); }); observer.observe(document.body, { childList: true, subtree: true }); } runWhenReady(); })();逐段解释一下。expandAllCodeBlocks 负责自动点击展开按钮injectPrintStyle 把上一节的样式以幂等方式注入因为脚本运行完页面还在我不想样式被重复插入导致页面卡顿所以先检查 id 存不存在hideRunProjectCard 用文本匹配滚动查找“该文章已生成可运行项目”的卡片找到就隐藏addPrintButton 在右下角挂一个绿色按钮最后用 MutationObserver 监听页面变化懒加载的代码段渲染出来后也会被自动展开。这里有个细节值得说cleanPrint 里 window.print() 之前留了 800 毫秒的缓冲。原因是我观察到有些折叠代码点击展开后容器高度动画还没跑完就触发打印预览里偶尔会出现代码被截断的情况。留 800ms 让动画结束基本能杜绝这个问题。如果你机器性能差一点可以把这个数值改到 1200。3.3 安装与使用三分钟跑起来安装步骤不复杂。在浏览器安装 Tampermonkey 扩展Edge、Chrome、Firefox 都有对应版本。完成后能看到工具栏出现油猴图标。点击图标选“添加新脚本”把上面整段代码粘贴进去按 CtrlS 保存。打开任意一篇 CSDN 文章页右下角会出现绿色的“清洁打印”按钮。需要打印时点一下按钮浏览器弹出打印预览。确认页面干净后保存为 PDF 或直接打印。实测下来整个脚本在近期的 CSDN 页面结构上运行稳定展开、隐藏、打印三个动作能衔接上。如果某天你发现按钮还在但打印结果里出现了新的广告位多半是 CSDN 前端又加了新组件这时候去 Elements 面板定位新组件在 injectPrintStyle 的隐藏列表里追加一行即可。3.4 脚本失效的常见原因和自查思路按钮没出现检查油猴脚本状态是否开启match 是否匹配当前网址。CSDN 域名偶尔会插入动态跳转参数但路径里 /article/details/ 这个模式基本稳定。按钮在但代码没展开CSDN 调整了按钮文案正则没命中。进控制台手动跑一遍 expandAllCodeBlocks如果控制台输出 0说明关键词需要改。还有一个可能是文章内容在 iframe 里这时要在 iframe 的上下文里执行脚本处理思路一样。打了代码跨页page-break-inside: avoid 对特长的代码块不是万能的一个代码块超过一页时仍会切断。建议把没有横向滚动条的短代码的字体调回 9pt太长的代码先在编辑器里拆成多段再打印。“该文章已生成可运行项目”卡片还残留说明它的 DOM 结构和文本匹配没对上。直接在 Elements 里找到它的外层容器手动补一个更精确的选择器。4. 别忽略打印对话框同样的干净页面设置不同效果天差地别4.1 “背景图形”不勾代码块直接变白板这里要讲一个很多教程都不讲透的点。浏览器默认在打印时是不输出背景颜色和背景图片的目的是省墨。问题来了我们的代码块样式里有 background: #f6f8fa如果你不勾选打印预览里的“背景图形”选项这个浅灰背景不会出现在纸张或 PDF 里。代码块的文字还在只是没有了底色和边框视觉上会和正文混在一起分不清哪里是代码哪里是段落。所以每次打印前把 CtrlP 弹出的预览窗口往“更多设置”里翻找到“背景图形”并勾上。如果有边框也一并勾选这样 pre 的 1px 边框才能显示出来。我见过有人辛辛苦苦配好了样式最后忘了这一步打印出来还是白板一块然后跑来问脚本是不是失效了。其实不是纯粹是打印选项少勾了一个。4.2 页边距、页眉页脚和纸张大小的取舍浏览器打印对话框默认会给页面加页眉页脚里面是 URL 和日期。技术资料存档的时候有页码其实是好事但 URL 往往一长串特别碍眼。我的建议是保留页码去掉 URL 和时间。做法是在打印预览的“更多设置”里关闭“页眉页脚”然后利用 CSS 的 page 规则只放页码或者干脆接受浏览器自带的页码。页边距方面默认的“默认”选项有时候是上下左右不对称的。技术文档排版我喜欢统一设成 1.2cm 到 1.5cm 之间四边一致看起来整齐。纸张大小默认 A4 就行。如果你想换 A5 或 B5注意代码块的 pre 的 padding 和字体大小也要跟着微调否则换行会很碎。4.3 关于分页断行的处理经验分页问题我踩过几次坑。一次是打印一篇特别长的教程正文里好几处标题刚好落在页面的最底部标题底下对应的正文跑到了下一页读起来非常割裂。CSS 里的 page-break-after: avoid 就是解决这个问题的加在 h1-h4 上标题就不会孤独地待在页尾。另一种情况是代码块内部换行太频繁把原本可以并排的短代码拆成了三四行。pre 的 white-space: pre-wrap 已经帮我们避免溢出但它会让每一个系统换行都真实呈现。我觉得比较稳妥的做法是一段代码控制在 40 行以内超过就手动拆成多个小代码块。打印稿不是上屏读代码太长的单块代码再怎么优化也不如拆开好翻。5. 把这套思路复制到其他网站以及我攒下来的使用习惯5.1 通用化改造换一套选择器能得到所有“干净打印”方案说实话我在文章开头说的方案不挑平台。CSDN、掘金、博客园、知乎、公众号做成油猴脚本时只要改三样东西match 的网址规则、正文容器的选择器、待隐藏元素的列表。以博客园举例正文容器一般是 #cnblogs_post_body代码块是 pre干扰元素主要是 .postDesc 和 .c_ad。掘金则要隐藏 .article-end 之类。代码里的 expandAllCodeBlocks 和 injectPrintStyle 的框架完全不用动。我甚至把这个脚本复制了一份把 name 改成“通用网页打印助手”match 改成 *然后把自己常用的站点选择器做成一个 Map根据 location.hostname 自动匹配。这套东西用到现在已经快一年依然顺手。5.2 打印前加目录、加行号这类进阶玩法如果你印刷的是连载教程或者几十页的手册光靠原文章的标题层级不够。我后来在脚本里加了一个可选功能打印前遍历正文的 h2-h3在文章最前面插入一个简单的目录列表目录项带锚点链接。打印到纸上时锚点当然点不了但目录保留标题和页码用处是让读者快速知道这篇文献覆盖了哪些章节。加行号其实更简单给 pre 内第一列铺一个 counter 就行。我个人很少用因为多数代码块很短行号意义不大但如果打印的是算法源码行号能提升对代码讨论的效率。你可以按需实现原理就是在 pre 左边画一块数字区配合 CSS counters 生成递增序号不涉及 DOM 重排。5.3 我的个人习惯打印成 PDF 再决定要不要上纸最后说一点建议。大部分时候我按下“清洁打印”按钮后并不会直接连打印机而是先在对话框里选“另存为 PDF”。一个直接原因PDF 可以永久保存、随时分享、二次排版。另一个原因是 PDF 版的排版结果就是打印机的输出效果如果 PDF 都挤成一团那上纸只会更糟。先看 PDF 再决定是否打印能省下不少纸。如果真要上纸我会在 PDF 生成后翻一遍确认每个代码块的边界完整、每页页尾没有孤立标题然后再点打印。双面打印记得关掉页眉页脚里的日期内容多的话打印成双面还会自然形成小册子的效果用起来比一份八九页的单面材料舒服很多。大概就是这些了。打印 CSDN 文章这件事本身不复杂只是隐藏的坑多。把这套脚本存好以后再遇到“该文章已生成可运行项目”这种卡片就不会再弄脏你的打印稿了。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询