牛逼,這個(gè) PDF 庫(kù)比其它工具好用 99 倍
閱讀本文大概需要 3 分鐘。
將網(wǎng)頁(yè)轉(zhuǎn)換為pdf之前用過(guò) wkhtmltopdf 這個(gè)工具,對(duì)應(yīng)的 Python 庫(kù)是 pdfkit,但是最終轉(zhuǎn)換出來(lái)的效果總是不盡如意。
最近發(fā)現(xiàn)一個(gè)新的庫(kù) WeasyPrint , 經(jīng)過(guò)一番測(cè)試效果非常不錯(cuò),無(wú)論是從官方網(wǎng)站的介紹還是提供的文檔,看得出作者應(yīng)該是花了不少心思來(lái)做這件事。
最重要的是,安裝簡(jiǎn)單,使用方便。不像pdfkit調(diào)用的都是 wkhtmltopdf 提供的指令,而 WeasyPrint 是一個(gè)原生的Python項(xiàng)目,所以特別適合做 Python 定制開發(fā),當(dāng)然,它也需要依賴其它第三方庫(kù)。
安裝
WeasyPrint 能在 Linux, macOS and Windows 多平臺(tái)支持,因?yàn)閃easyPrint需要依賴 cairo, Pango 和 GDK-PixBuf ,所以這些軟件需要獨(dú)立安裝,而 WeasyPrint 可以直接通過(guò) pip 安裝。
Mac
brew install python3 cairo pango gdk-pixbuf libffiWindow
Windows的安裝要稍微麻煩些, 主要是安裝 GTK+ 這個(gè)庫(kù),下載地址:https://github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases/download/2020-11-22/gtk3-runtime-3.24.23-2020-11-22-ts-win64.exe
安裝WeasyPrint
pip install WeasyPrint不出意外的話,你現(xiàn)在就可以使用 WeasyPrint 這個(gè)工具了。執(zhí)行 weasyprint 命令, 指定要轉(zhuǎn)換的 url 地址和 pdf 文件名即可。
我們隨便指定一個(gè) URL 地址,這里以我的博客為例
weasyprint https://foofish.net/base64.html base64.pdf最后生成的效果圖

這就完了嗎?
肯定不是,如果只是單純的轉(zhuǎn)換一個(gè)網(wǎng)頁(yè),直接用瀏覽器的打印功能,然后另存為 PDF 就可以了。沒(méi)必要繞個(gè)這么大的彎子來(lái)做這件事。
我們之所以用它來(lái)做 PDF 轉(zhuǎn)換肯定是希望它能夠?yàn)槲覀儗?shí)現(xiàn)自動(dòng)化、批量化、個(gè)性化的任務(wù)。
構(gòu)建 HTML 對(duì)象
生成 PDF 文件前,首先需要構(gòu)建一個(gè) HTML 對(duì)象,HTML 對(duì)象可以通過(guò) url 鏈接、文件路徑,或者是 HTML 文檔字符串指定
from weasyprint import HTML
HTML(filename='../foo.html')
HTML(url='http://weasyprint.org')
HTML(string='''
The title
Content goes here
'''
)生成 pdf 文件只需要調(diào)用 html 對(duì)象的 write_pdf 方法
一個(gè)最簡(jiǎn)單的例子:
from weasyprint import HTML
HTML('https://foofish.net/base64.html').write_pdf('base64.pdf')在轉(zhuǎn)換的時(shí)候,你還可以自定義樣式
from weasyprint import HTML, CSS
HTML('https://foofish.net/base64.html').write_pdf('base64.pdf',
stylesheets=[CSS(string='body { font-family: serif !important }')])當(dāng)然不僅可以生成PDF,也可以生成PNG圖片, 只需要調(diào)用 html.write_png(“filename.png”)。
Document對(duì)象
此外,HTML 對(duì)象的 render 方法返回一個(gè) document 對(duì)象,通過(guò) document 對(duì)象可以拿到所有頁(yè)碼(page)數(shù)據(jù),這樣你就可以獲取指定頁(yè)的數(shù)據(jù)來(lái)生成 PDF 或者將多個(gè) HTML 的 document 對(duì)象合并成一個(gè) PDF 文件。
例如,將每頁(yè)單獨(dú)生成一張圖片
html1 = HTML("https://foofish.net/base64.html")
document = html1.render()
for i, page in enumerate(document.pages):
document.copy([page]).write_png('page_%s.png' % i)
例如:將兩個(gè)鏈接整個(gè)生成一個(gè)PDF文件
html1 = HTML("https://foofish.net/base64.html")
html2 = HTML("https://foofish.net/python-wsgi.html")
pages = []
pages.extend(html1.render().pages)
pages.extend(html2.render().pages)
HTML(string="").render().copy(pages).write_pdf("foofish.pdf")
完
