以前の投稿で利用したChrome DevTools Protocolを活用して、Seleniumで表示したページをPDFに保存します。
cdp-pdf.py
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
import base64
def save_to_pdf(driver, file_path):
parameters = {
"printBackground": True, # 背景画像を印刷
"paperWidth": 8.27, # A4用紙の横 210mmをインチで指定
"paperHeight": 11.69, # A4用紙の縦 297mmをインチで指定
# "displayHeaderFooter": True, # 印刷時のヘッダー、フッターを表示
}
# Chrome Devtools Protocolコマンドを実行し、取得できるBase64形式のPDFデータをデコードしてファイルに保存
pdf_base64 = driver.execute_cdp_cmd("Page.printToPDF", parameters)
pdf = base64.b64decode(pdf_base64["data"])
with open(file_path, 'bw') as f:
f.write(pdf)
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-gpu')
# Webdriver ManagerでChromeDriverを取得
driver = webdriver.Chrome(
executable_path=ChromeDriverManager().install(),
options=options
)
driver.get('https://qiita.com/')
save_to_pdf(driver, 'qiita.pdf')
driver.close()
driver.quit()
- Page.printToPDFというメソッドでPDFを出力します。
- Headlessでなく普通にブラウザを立ち上げる状態(非Headless)で試すと、
{"code":-32000,"message":"PrintToPDF is not implemented"}
というエラーになりました。- Puppeteer(Chrome DevTools Protocolを介してHeadless Chromeを操作するNode.jsライブラリ)のドキュメントの情報によると、現在、PDFの生成はHeadless Chromeのみのサポートのようです。
- Headlessでない状態でのPDF作成は、以下の記事の内容で実現できそうです。
[PythonのSeleniumでログインありのwebページをPDF保存する - Qiita -] (https://qiita.com/kuro227/items/838b9bab231902e280d4)
- 長さを指定する際の単位はインチ(1 in = 25.4 mm)のようです。A4サイズ(210mm X 297mm)となるように指定しましたが、生成されたPDFの情報を見るとぴったりにはならずに微妙に違っていました。
-
headerTemplate
、footerTemplate
というパラメータでヘッダ・フッターのデザインを変えることができます。こちらはVSCodeでmarkdown → PDF変換を行うmarkdown-pdfという拡張機能に関する情報が役立つかもしれません。