- 文档
- 后端
【免费下载链接】WeasyPrint
The awesome document factory
本文以仓库内 docs/changelog.rst 为骨架,系统梳理 WeasyPrint 从 2011 年首个打包版本 v0.1 到 2026 年 v70.0 的全部版本记录,重点解读四次安全更新(CVE)、命令行与 Python API 的破坏性变更、CSS/PDF 能力的里程碑式扩展,以及 Python 版本与系统依赖的演进路径,并辅以仓库源码实现佐证。读完本文,你将掌握 WeasyPrint 的版本历史全貌、各版本之间的迁移要点、常见安全风险的规避方式,以及如何结合 weasyprint/ 源码理解这些变更背后的实现逻辑。
一、版本记录概况:15 年演进的时间线
WeasyPrint 是面向打印场景的 HTML/CSS 渲染引擎,可将 HTML 页面转为 PDF,其 CSS 排版引擎用 Python 编写、专为分页设计(见 README.rst)。docs/changelog.rst 以倒序方式记录了从 v70.0 到 v0.1 的全部版本,主要版本节奏如下:
| 版本区间 | 发布时间 | 阶段特征 |
|---|---|---|
| v0.1 – v0.42.3 | 2011-10 至 2018-03 | 早期构建期:表格、浮动、Acid2、PDF 书签/超链接、0.x 收尾 |
| v43 – v52 | 2018-10 至 2020-10 | 现代化重构期:Flexbox、target counters、自有 PDF 生成器、Pillow |
| v53 – v60 | 2021-04 至 2023-09 | 功能爆发期:PDF/A、PDF/UA、脚注、表单、字体子集化、Grid |
| v61 – v70 | 2024-02 至 2026-09 | 合规与安全期:PDF 变体细化、颜色管理、多次安全更新 |
每个版本条目都遵循固定结构:Security(安全)、Dependencies(依赖)、Command-line API(CLI)、Python API、Features(新功能)、Bug fixes(缺陷修复)、Performance(性能)、Documentation(文档)、Contributors(贡献者)、Backers and sponsors(赞助者),并关联对应的 GitHub issue/PR 编号,是回溯具体变更原因的一手资料。
二、安全更新:四个必须关注的 CVE
changelog 中明确标注为 "security update" 的版本共有四个,均建议用户立即升级,是评估是否升级的核心依据。
1. v70.0(2026-09-08):CVE-2026-55073
官方建议以下两类用户必须升级:
- 嵌入不受信任图片的用户:本版本起不再渲染 EPS 图像,堵住了恶意 EPS 文件可能带来的攻击面;
- 依赖 URL fetcher 过滤元数据或样式表的用户:本版本起始终使用原始 URL fetcher,避免过滤被绕过。
该版本还配套了若干加固型变更,例如 "Log an error on unknown render and write_pdf options"(对未知渲染选项与 write_pdf 选项输出错误日志)以及 "Don't use f-strings in logs",减少日志注入与信息泄漏风险。
2. v69.0(2026-06-02):CVE-2026-49452
风险场景:使用--presentational-hints选项且用受限 CSS 属性渲染不受信任的 HTML 时存在CSS 注入。修复方式是改用 HTML 解析器处理 presentational hints(对应 issue #2636/#2720/#2773),从解析层杜绝注入。
3. v68.0(2026-01-19):CVE-2025-68616
风险场景:在自定义 URL fetcher 中使用default_url_fetcher函数,或使用其allowed_protocols参数。修复为HTTP 重定向一律走 URL fetcher,防止协议限制被重定向绕过。仓库中 weasyprint/urls.py 的URLFetcher类正是这次重构的产物——它继承urllib.request.OpenerDirector,通过allowed_protocols参数(None表示允许全部协议)在fetch()入口处校验 URL scheme,并在构造函数中按需挂载HTTPRedirectHandler。
4. v61.2(2024-03-08):附件 URL fetcher 强制化
修复 "Always use URL fetcher for attachments",影响范围为 v61.0 与 v61.1 用户。
升级建议:如果你的生产环境涉及不受信任的 HTML/图片输入,或自定义了 URL fetcher,应至少升级到 v68.0 及以上;若还使用--presentational-hints,则应升级到 v69.0 及以上;当前最新安全版本为 v70.0。
三、核心功能里程碑:从 CSS 2.1 到 CSS Color 4 / Grid / Notes
changelog 展示了 WeasyPrint 按打印场景逐步补齐现代 CSS 能力的完整路径,可归纳为五条主线。
1. 布局引擎:分页、浮动、Flexbox、Grid、Columns
- v0.11(2012-07):支持
float与clear,并因此通过 Acid2 测试,Acid2 自此纳入自动化测试套件; - v43rc1(2018-10):Flexbox 初始支持;
- v62.0(2024-04):完整支持CSS Grid Layout(issue #543/#2121),随后 v62.1–v63.0 持续修复网格分页、空页首行渲染等边界问题;
- v63.0(2024-10):支持页面组(page groups),使连续页面可以共享统一的页边距盒子上下文;
- v67.0(2025-12):允许网格行内分页(issue #2397),对长表格类文档意义重大;
- v70.0(2026-09):支持
box-shadow,并将阴影标记为PDF artifacts(issue #2882/#2883),避免影响无障碍阅读顺序。
分页相关的break-*属性在 v50(表格内分页)、v55.0b1(列内分页)、v54.1(break-inside: avoid作用于<tr>)等版本中持续完善;orphans/widows早在 v0.7 即已支持。
2. 颜色、渐变与颜色管理
- v67.0:支持CMYK 颜色、PDF/X、色彩配置文件与
light-dark()函数(issue #640 等),并新增rch、cap、rcap、rex、ic、ric等字体相对单位; - v63.0:支持CSS Color Level 4(issue #1630/#2286);
- v69.0:新增PDF output intent(输出意图)设置能力(issue #2631/#2778),可在 CLI 与 Python API 中指定 sRGB、device-cmyk 或
@color-profile规则标识符。
仓库中 tests/draw/test_cmyk_color_profiles.py 与 weasyprint/pdf/pdfx.py 分别从测试与实现两个角度印证了 CMYK/PDF/X 的能力。
3. 数学函数、单位与逻辑属性
- v53.0b1:新增 ISO/JIS 纸张规格与
leader()函数(用于目录点线); - v67.0:全面支持
calc()及其他数学函数(issue #357/#2568); - v69.0:支持逻辑属性(
margin-inline、padding-block等,issue #2357/#2700)与视口单位(vw/vh等,issue #1194/#2702); - 更早的 v0.19 已引入
ex/ch单位,v0.27 支持rem,v66.0 支持lh/rlh。
4. 内容生成与分页媒体:页眉页脚、书签、target counters
- v0.9:PDF 书签(bookmarks)与内/外部超链接;
- v0.40:命名页(named pages);
- v47:CSS 变量;
- v49:
::marker伪元素、recto/verso分页方向; - v51:
element()与running()(running headers); - v54.0b1:**脚注(footnotes)**支持,由 Code & Co. 资助;v66.0 起持续修复多栏脚注、孤儿行脚注溢出等问题;
- v70.0:新增CSS Notes 初始支持(issue #2905,NLnet 资助)——这是继 footnotes 之后分页媒体领域的又一内容机制。
5. 文本、字体与排版细节
- v0.32:Linux 下
@font-face、OpenType 特性支持; - v56.0b1:位图字体(bitmap fonts)支持(Expert Germany 资助);
- v57.0b1:**可变字体(variable fonts)**支持;
- v63.0:HarfBuzz 成为默认字体子集化引擎(替换 fontTools,issue #2120/#2178);v70.0 起对 fontTools 子集化路径添加弃用警告;
- v65.0:
@font-face的unicode-range支持; - v70.0:COLR emoji 字体支持(issue #2777/#2814),并修复栅格 emoji 的位置问题。
四、命令行与 Python API:两次重要的破坏性变更
1. v59.0:全局渲染选项改为**options
v59.0b1(2023-04-14)对 CLI 与 Python API 做了大规模重构,这是自 v53 自研 PDF 生成器之后最重要的一次 API 调整。
CLI 侧:--optimize-size/-O被弃用,拆分为六个独立选项:
| 选项 | 作用 |
|---|---|
--uncompressed-pdf | 输出不压缩的 PDF |
--optimize-images | 优化嵌入图像体积 |
--full-fonts | 嵌入完整字体(不做子集化) |
--hinting | 保留嵌入字体的 hinting 信息 |
--dpi <resolution> | 设置图像分辨率 |
--jpeg-quality <quality> | 设置 JPEG 压缩质量 |
--cache-folder <folder> | 将临时数据存到磁盘目录而非内存 |
Python API 侧:HTML.render()、HTML.write_pdf()、Document.write_pdf()的签名改为**options,迁移步骤为:
- 一律使用命名参数,不要使用位置参数;
- 重命名参数:
image_cache→cache、identifier→pdf_identifier、variant→pdf_variant、version→pdf_version、forms→pdf_forms; - 删除
optimize_size参数,改用uncompressed_pdf、full_fonts、hinting、dpi、jpeg_quality等新参数。
cache参数支持三种形态:None(内存默认)、字典(可跨文档共享的内存缓存)、目录路径或Path(磁盘缓存)。该实现可见于 weasyprint/document.py:_build_layout_context中先判断cache是否为字典或DiskCache,否则包装为DiskCache。
2. v69.0:--srgb变为--output-intent
v69.0 将--srgb布尔开关升级为--output-intent,可取三类值:
srgb:等价于旧行为,指定 sRGB 输出意图;device-cmyk:无 ICC 配置文件的 CMYK 文档;- CSS
@color-profile规则中的自定义标识符。
Python API 同步将默认选项中的srgb布尔值替换为output_intent字符串。在 weasyprint/document.py 中可以看到output_intent被作为Document构造参数持久化,并在写入 PDF 时参与色彩空间处理。
3. v70.0:未知选项报错
v70.0 起,向render/write_pdf传入未知选项会记录错误日志,帮助用户尽早发现拼写错误或版本不兼容的选项名。
4. v68.0:URL fetcher API 重构
default_url_fetcher()函数被弃用,取而代之的是 weasyprint/urls.py 中的URLFetcher类,构造参数包括:
timeout:HTTP 请求超时秒数(默认 10);ssl_context:自定义 HTTPS SSL 上下文;http_headers:附加 HTTP 请求头;allowed_protocols:允许的协议集合,None表示全部;allow_redirects:是否跟随 HTTP 重定向;fail_on_errors:HTTP 错误是否中止渲染。
同时DocumentMetadata.generate_rdf_metadata由参数改为可覆写的方法,为 Factur-X/ZUGFeRD 电子发票等自定义 RDF 元数据场景提供了扩展点(详见 docs/going_further.rst 相关章节)。
5. 更早的 CLI/API 变更备忘
- v53.0:
--format/--resolution弃用(PDF 成为唯一输出格式);--optimize-images被--optimize-size(取值images/fonts/all/none)取代;FontConfiguration迁移到weasyprint.text.fonts模块; - v61.0:
DocumentMetadata.attachments从(url, description)元组列表变为Attachment对象列表; - v60.0:新增
--timeoutCLI 选项; - v45:新增
--quiet与--debugCLI 参数。
五、依赖与平台要求演进:升级前必查
changelog 中反复出现 "Dependencies" 章节,以下是 Python 解释器与核心库的版本门槛时间线:
| 版本 | Python 要求 | 关键依赖变化 |
|---|---|---|
| v0.37 | — | tinycss2 取代 tinycss |
| v0.40 | — | cssselect2 取代 cssselect + lxml |
| v43rc1 | 3.4+,放弃 Python 2.x | Cairo 1.15.4+,移除 pdfrw |
| v52 | 3.6+ | 新增依赖 Pillow |
| v53.0b1 | — | 自研 PDF 生成器(pydyf)取代 Cairo;Flit 打包 |
| v55.0b1 | 3.7+ | — |
| v62.0 | 3.9+ | pydyf 0.10+、tinycss2 1.3+ |
| v63.0 | 3.13 受支持 | tinyhtml5 2.0+ 取代 html5lib;pydyf 0.11+;tinycss2 1.4+ |
| v67.0 | 3.10+,3.9 不再支持 | tinycss2 1.5.0+、fontTools 4.59.2+ |
| v65.0 | — | CSSSelect2 0.8.0+ |
| v57.1 | — | Pillow 9.1.0+ |
| v53.0 | — | Pango 1.44.0+、pydyf 0.0.3+、fontTools 4.0.0+ |
值得注意的里程碑:v53.0b1 起 WeasyPrint 使用自己的 PDF 生成器(基于 pydyf)替代 Cairo,这意味着文本、渐变、SVG 图像的渲染细节从此由 WeasyPrint 自己掌控;v63.0 起 HTML 解析从 html5lib 切换到 tinyhtml5;v67.0 将 Python 下限提升到 3.10——如果你的运行环境仍停留在 Python 3.9,这是必须规划升级的硬性门槛。
六、性能与文档:贯穿始终的优化主线
changelog 专设 Performance 与 Documentation 章节,代表性工作包括:
- v0.40/v0.42:优化长文档的速度与内存占用;
- v52:图片缓存可跨文档共享;
- v59.0b1:降低 PDF 体积与图片内存占用(Code & Co. 资助),新增字体 hinting 保留选项;
- v63.0:大
colspan表格渲染提速、HarfBuzz 子集化提速; - v70.0:元素间共享计算样式(issue #2813)、均匀虚点边框改用 stroked dashes 绘制(issue #2526/#2776)、SVG 路径解析加速(issue #2913)。
文档侧的重要节点包括:v45 引入独立 logger 并完善自定义 url_fetcher 文档;v60 补充--timeout;v63 完善 Alpine 安装说明并增加调试日志;v69 补充纸张大小与方向的命令行选项说明;v70 记录"源码变更后自动重新生成 PDF"的工作流(issue #1360/#2865)。完整 API 参考见 docs/api_reference.rst,使用场景见 docs/common_use_cases.rst。
七、迁移与升级检查清单
综合 changelog 中所有带标注的破坏性变更,升级到 v70.0 时可对照以下清单:
- Python 版本:确认运行环境为 Python 3.10+(v67.0 起),并在 CPython 与 PyPy 上测试(README 声明);
- URL fetcher:若自定义了 fetcher,将
default_url_fetcher迁移到URLFetcher子类,并注意重定向、allowed_protocols语义(v68.0); - 渲染选项:检查
render/write_pdf的命名参数,确认使用pdf_variant、pdf_version、pdf_forms、pdf_identifier、cache等新名称(v59.0); - 颜色配置:如使用
--srgb,改用--output-intent=srgb(v69.0); - 附件元数据:
DocumentMetadata.attachments现在是Attachment对象列表(v61.0); - PDF 输出意图与变体:PDF/A、PDF/UA、PDF/X 相关选项见 weasyprint/pdf/pdfa.py、weasyprint/pdf/pdfua.py、weasyprint/pdf/pdfx.py;
- 安全基线:优先升级到 v70.0(CVE-2026-55073),尤其当输入包含不受信任图片或自定义 fetcher 时。
八、如何在当前仓库中进一步验证
- 阅读完整版本记录:docs/changelog.rst;
- 查看 URL fetcher 实现:weasyprint/urls.py;
- 查看渲染选项与 PDF 变体处理:weasyprint/document.py;
- 查看 CLI 入口(
--output-intent等选项):weasyprint/main.py; - 运行相关测试以复现核心能力:CMYK 色彩配置 tests/draw/test_cmyk_color_profiles.py、计数与目标引用 tests/css/test_counters.py、PDF 输出 tests/test_pdf.py。
从 2011 年的 "simple CSS 2.1 pages" 到 2026 年的 CSS Notes、COLR emoji、PDF/X 与多次 CVE 修复,docs/changelog.rst 完整记录了 WeasyPrint 作为"文档工厂"的进化史。对于使用者而言,最重要的三条主线是:跟随安全版本、在破坏性 API 变更点做好迁移、以及利用 Performance/Documentation 条目评估升级带来的收益。
- 文档
- 后端
【免费下载链接】WeasyPrint
The awesome document factory
相关推荐
Cosign 版本演进全解:从 v0.1 到 v3.0 的签名能力变迁与升级迁移指南
Cosign 版本演进全解:从 v0.1 到 v3.0 的签名能力变迁与升级迁移指南 本篇技术指南以仓库根目录的 CHANGELOG.md https://li
供应链安全云原生应用安全Streamlink 版本演进全景:从 0.0.1 到 8.6 的核心变更、安全修复与迁移要点
Streamlink 版本演进全景:从 0.0.1 到 8.6 的核心变更、安全修复与迁移要点 导读 本文以 Streamlink 官方版本记录( docs/c
音视频BTCPay Server Changelog 全解读:从 1.0.4 到 2.4.3 的功能演进、安全修复与升级指南
BTCPay Server Changelog 全解读:从 1.0.4 到 2.4.3 的功能演进、安全修复与升级指南 本篇文章以开源自托管比特币支付处理器 B
区块链金融科技后端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考