
本文介绍如何利用 selenium 的 chrome devtools 协议(cdp)直接生成高质量、文字可选中/可搜索的 pdf,解决滚动截长页失败、内容截断及排版失真等问题,并通过缩放、纸张尺寸优化和 pymupdf 后处理提升兼容性与可读性。
本文介绍如何利用 selenium 的 chrome devtools 协议(cdp)直接生成高质量、文字可选中/可搜索的 pdf,解决滚动截长页失败、内容截断及排版失真等问题,并通过缩放、纸张尺寸优化和 pymupdf 后处理提升兼容性与可读性。
在网页自动化导出 PDF 场景中,许多开发者尝试通过滚动+分页截图再拼接的方式生成长文档,但这不仅破坏文字的连续性(导致 PDF 不可搜索),还极易因动态加载、懒加载或 CSS 布局干扰而丢失内容。Selenium 原生支持 Chrome DevTools Protocol(CDP)的 Page.printToPDF 命令——它基于浏览器渲染引擎直接输出矢量 PDF,天然保留文本层、字体嵌入和语义结构,确保生成的 PDF 完全可选中、可复制、可搜索,无需 OCR。
关键在于正确配置 CDP 参数与页面渲染状态。原代码中仅调整 paperWidth/paperHeight 不足以适配复杂 SPA 页面(如 Coursera),因其高度依赖视口缩放、CSS 媒体查询及动态布局计算。实测表明:强制设置 document.body.style.zoom 可统一渲染比例,避免内容被截断或折叠;同时扩大 paperHeight 并微调 paperWidth 能有效容纳完整 DOM 高度。推荐配置如下:
# 在执行 printToPDF 前注入缩放并设置大纸张尺寸
driver.execute_script("document.body.style.zoom = '0.9';") # 90% 缩放,提升内容完整性
params = {
"landscape": False,
"paperWidth": 12, # 单位:英寸(≈304.8mm),宽于 A4(8.27")
"paperHeight": 25, # 高度设为足够大(≈635mm),覆盖长页面
"printBackground": True,
"preferCSSPageSize": False # 关键!禁用 CSS page-size 干扰
}
result = driver.execute_cdp_cmd("Page.printToPDF", params)
pdf_bytes = base64.b64decode(result["data"])
with open("output.pdf", "wb") as f:
f.write(pdf_bytes)
⚠️ 注意事项:
- 切勿滚动后调用
printToPDF:CDP 打印始终基于当前 DOM 快照,滚动仅影响视口,不改变printToPDF的渲染范围;- 禁用
preferCSSPageSize=True(默认为False),否则 CSS 中的@page { size: ... }可能强制裁剪;zoom值需根据目标网站实测调整(0.8–0.95 常见),过小导致字体过细,过大则内容溢出;- 确保页面完全加载(建议
WebDriverWait(driver, 15).until(EC.presence_of_element_located(...)))后再执行打印。
生成的 PDF 可能存在边距过大、尺寸不标准(如超宽)等问题,影响 GitHub 预览或打印。此时可用 PyMuPDF(fitz)进行无损重排版:保持原始文本层不变,仅裁剪冗余边距、重设为标准 A4 尺寸,并自动适配横/纵版式:
import fitz
src = fitz.open("output.pdf")
doc = fitz.open()
for page_num in range(src.page_count):
src_page = src[page_num]
# 裁剪左右各 30pt 边距(保留顶部/底部)
clip = fitz.Rect(src_page.rect.x0 + 30, src_page.rect.y0,
src_page.rect.x1 - 30, src_page.rect.y1)
# 自动选择 A4 或 A4-Landscape
fmt = fitz.paper_size("a4-l") if src_page.rect.width > src_page.rect.height else fitz.paper_size("a4")
dst_page = doc.new_page(width=fmt[0], height=fmt[1])
dst_page.show_pdf_page(dst_page.rect, src, page_num, clip=clip)
doc.save("output_a4.pdf")
doc.close()
src.close()
最终生成的 PDF 具备以下特性:✅ 原生可搜索文本 ✅ 支持 Ctrl+F 查找 ✅ 字体清晰无锯齿 ✅ 标准 A4 尺寸 ✅ GitHub / Acrobat / Edge 等主流阅读器兼容。该方案替代了截图+OCR 的低效路径,真正实现「所见即所得」的高质量网页归档。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











