我尝试使用 pdfkit 将网页转换为 PDF。当使用 google.com 等 URL 时,此方法效果很好。但是当我尝试转换在 NextJS 中构建的网页时,PDF 工具包不断加载而没有任何响应。
我使用 imbd.com 作为示例,因为他们也在使用 NextJS。
import pdfkit
try:
options = {
# 'page-size': 'A4',
'encoding': 'utf-8',
'margin-top': '0cm',
'margin-bottom': '0cm',
'margin-left': '0cm',
'margin-right': '0cm',
# 'image-quality': '1000',
# 'image-dpi': '2000',
'disable-smart-shrinking': '',
'page-width': '595px',
'page-height': '842px',
'no-outline': None,
'javascript-delay': '1000',
"load-error-handling": "ignore"
}
pdfkit.from_url(
'https://www.imdb.com/', 'out.pdf', options=options, verbose=True)
except Exception as e:
raise e
运行上述脚本时没有任何反应。而且调试时也没有可以使用的错误日志记录。
为了调试,我尝试直接与
wkhtmltopdf
交互,但仍然没有得到任何输出。
我的命令:
$ wkhtmltopdf --javascript-delay 5000 --debug-javascript http://imdb.com out.pdf
输出: 加载程序冻结在 87%,并且没有任何输出可以帮助我找出问题所在。
Loading pages (1/6)
[====================================================> ] 87%
在选项对象的“javascript-delay”下,尝试将阈值增加到 5000。
您没有使用正确的包,pdfkit 适合捕获在服务器端呈现的网站。像 React 这样的 NextJ 不会在服务器上渲染,服务器渲染的 HTML 也会在服务器上渲染,但它们会在客户端渲染,因此会永远等待渲染。 为此,您可以尝试使用curl 获取网站的HTML 来查看差异,您将看到大量在客户端呈现的javascript。
为此,您需要一个使用 chrome headless 的库,例如,我推荐 pyhtml2pdf 。 你需要:
pip install pyhtml2pdf
#install also chrome or chromium if is not installed
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt -y install ./google-chrome-stable_current_amd64.deb
然后您可以使用以下简单代码来捕获网站:
from pyhtml2pdf import converter
converter.convert('https://www.imdb.com', 'sample.pdf')
按预期工作并且网站已呈现。
您有两个主要问题,一个是浏览器安全性,另一个是将网页打印为 PDF。
到目前为止,打印网站而没有任何次要安全问题的最简单方法是使用浏览器,因此参考不是问题。
Chrome --headless [Disable$*] --run-all-compositor-stages-before-draw --no-pdf-header-footer --print-to-pdf="/folder/out.pdf" https://www.imdb.com
主要问题是,它会完美/完全就像您将网页打印为 pdf 一样,而无需调整任何打印输出设置。所以它应该是A4纵向,因此媒体框应该不是问题,但设置边距更困难,特别是因为它不是设计为命令行驱动的,因此需要一个木偶操纵者(或更简单的基本用法,例如sendkeys)。
如果您需要进行商业级别调整,请考虑商业 URL2PDF SDK/API 解决方案,有几种设计用于与 Python 一起使用