
本文详解如何通过 selenium + chromedriver 实现网页自动“打印为 pdf”,避开浏览器弹出的交互式打印对话框,利用 `--kiosk-printing` 等关键参数实现静默导出,并提供稳定、可复用的完整代码方案。
在 Web 自动化场景中,常需将目标网页导出为 PDF 文件(如生成报告、存档页面等)。但直接调用 window.print() 会触发 Chrome 的图形化打印对话框,而 Selenium 默认无法操作该原生系统级 UI,导致脚本阻塞超时——这正是原始代码失败的根本原因。
要真正实现无交互、自动化、静默生成 PDF,必须绕过前端 JavaScript 的“触发打印”行为,转而配置 Chrome 启动参数,使其在调用 window.print() 后自动执行“另存为 PDF”动作。核心在于两个关键 Chrome 启动选项:
- --kiosk-printing:启用免提示打印模式,自动选择“另存为 PDF”打印机并确认保存;
- --no-sandbox 和 --disable-dev-shm-usage(推荐补充):提升容器/无头环境下的稳定性;
- ⚠️ 移除 --disable-gpu:该参数在新版 Chrome 中可能导致 PDF 渲染异常或打印流程中断;
- ⚠️ 移除 set_script_timeout():window.print() 是异步触发行为,设置脚本超时无实际意义,反而干扰流程。
此外,需配合合理的等待策略:implicitly_wait() 用于全局元素加载等待(非针对打印),而对 PDF 生成完成的判断,不能依赖 time.sleep() —— 因 PDF 写入是后台异步过程,更可靠的方式是监听输出目录中文件是否生成并具备合理大小(例如 >10 KB)。
以下为优化后的完整可运行示例(兼容 Chrome 115+,支持 Windows/macOS/Linux):
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import os
import time
def save_webpage_as_pdf(url: str, output_path: str, timeout: int = 30) -> bool:
"""
使用 Selenium 将指定 URL 页面静默保存为 PDF
:param url: 目标网页地址
:param output_path: PDF 输出路径(需包含 .pdf 后缀)
:param timeout: 最大等待时间(秒),用于检测 PDF 是否生成成功
:return: 成功返回 True,否则 False
"""
# 确保输出目录存在
os.makedirs(os.path.dirname(output_path), exist_ok=True)
chrome_options = Options()
chrome_options.add_argument("--kiosk-printing") # 关键:静默打印到 PDF
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--disable-background-timer-throttling")
chrome_options.add_argument("--disable-renderer-backgrounding")
# 注意:不要添加 --disable-gpu 或 --headless(除非明确需要无头,但 PDF 生成在有界面模式下更稳定)
# 设置下载路径(仅当使用 Chrome 默认 PDF 打印机时有效)
# 实际上,--kiosk-printing 会自动使用系统默认 PDF 打印机(即“另存为 PDF”),无需额外配置下载行为
driver = webdriver.Chrome(options=chrome_options)
try:
driver.implicitly_wait(10) # 全局隐式等待,用于页面加载和元素查找
driver.get(url)
# 等待页面基本内容加载(可选:根据实际需求加显式等待)
time.sleep(3)
# 触发打印 → 自动保存为 PDF
driver.execute_script("window.print();")
# 等待 PDF 文件生成(轮询检查)
start_time = time.time()
while time.time() - start_time < timeout:
if os.path.exists(output_path) and os.path.getsize(output_path) > 10 * 1024: # >10KB
print(f"✅ PDF 已成功保存至:{output_path}")
return True
time.sleep(1)
print(f"❌ 超时未检测到 PDF 文件生成,请检查 Chrome 版本及权限设置。")
return False
finally:
driver.quit()
# 使用示例
if __name__ == "__main__":
pdf_path = "output/google_homepage.pdf"
success = save_webpage_as_pdf("https://www.google.com", pdf_path)
if not success:
exit(1)✅ 关键注意事项总结:
- --kiosk-printing 必须与 window.print() 配合使用,单独设置无效;
- 该方案依赖 Chrome 内置的“另存为 PDF”虚拟打印机,无需额外安装 PDF 驱动;
- 若在 Docker 或 CI 环境中运行,建议添加 --headless=new(Chrome 112+)并确保已安装字体库(如 fonts-liberation),否则 PDF 可能出现乱码或空白;
- 对于需要精确控制页边距、纸张尺寸、背景图形等高级 PDF 样式的需求,建议改用 print_options(Chrome DevTools Protocol)方式,而非 window.print();
- 不要混淆“Print to PDF”(本方案)与“Save as HTML”或“MHTML”——二者技术路径与输出格式完全不同。
掌握这一模式后,即可将网页快照、报表、票据等一键固化为标准 PDF,无缝集成进自动化测试、监控告警或文档归档流水线。









