search
LoginSignup
13

More than 1 year has passed since last update.

posted at

updated at

SeleniumとHeadless ChromeでページをPDFに保存する

以前の投稿で利用した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"}というエラーになりました。
  • 長さを指定する際の単位はインチ(1 in = 25.4 mm)のようです。A4サイズ(210mm X 297mm)となるように指定しましたが、生成されたPDFの情報を見るとぴったりにはならずに微妙に違っていました。
  • headerTemplatefooterTemplateというパラメータでヘッダ・フッターのデザインを変えることができます。こちらはVSCodeでmarkdown → PDF変換を行うmarkdown-pdfという拡張機能に関する情報が役立つかもしれません。

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
13