2023年4月19日水曜日

seleniumでasciidocファイルをPDFに変換

これには
  • selenium に asciidoctor extension を入れる
  • PDFを指定して印刷する
の2つが必要。

Selenium に extensionを入れる

これには、
  • extensionのcrxファイルを入手する
  • crxファイルを指定してドライバをつくる
の2つが必要。

crxファイルの入手

crxファイルを入手する方法は このブログ に書かれている。ダウンロードをやってくれるサイトがあるらしいのだが、ドメインが切れたらしく 怪しいことになっていたので、再パッケージする方法を使う。 基本的には、chromeのextension のページで、pack extension ボタンで、導入されているextensionのパスを指定すれば いいのだが、そのパスがわからない。そんなときは、 chrome://version のProfilePathを見ればわかる。この下のExtensions以下にIDのディレクトリがある。 ディレクトリ名はIDだが、個々のExtensionのIDはchromeのextensionsのページ chrome://extensions/ を見ればわかる。 manifest.jsonにも アプリ名が入っているはずなのだが、メッセージファイルを参照している場合もあるようで、grepしてもわからない。

ドライバをつくる

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options=Options()
options.add_extension(pathToExtension)
driver = webdriver.Chrome("./chromedriver", options=options)

PDFを指定して印刷

こちらのサイトに書いてある。 しかしこれどうやって調べたんだろう。どこに書いてあるのかなあ。。

注意点としては、savefile.default_directory の指定はどうも絶対パスでないといけないようなので、 Pathを使って作ってやる必要がある。


pathToExtension="2.7.0_0.crx"

def optionsSetUp():
    #印刷としてPDF保存する設定
    options=Options()
    appState = {
        "recentDestinations": [
            {
                "id": "Save as PDF",
                "origin": "local",
                "account":""
            }
        ],
        "selectedDestinationId": "Save as PDF",
        "version": 2,
        "isLandscapeEnabled": False, #印刷の向きを指定 tureで横向き、falseで縦向き。
        "pageSize": 'A4', #用紙タイプ(A3、A4、A5、Legal、 Letter、Tabloidなど)
        "isHeaderFooterEnabled": False, #ヘッダーとフッター
        "isCssBackgroundEnabled": True, #背景のグラフィック
        "isCollateEnabled": True #部単位で印刷
    }
    
    prefs = {'printing.print_preview_sticky_settings.appState':
             json.dumps(appState),
             "savefile.default_directory": str(Path('../rendered').resolve())
             } #appState --> pref
    options.add_experimental_option('prefs', prefs)

    options.add_argument('--kiosk-printing')
    options.add_extension(pathToExtension)
    return options
    
    
driver = webdriver.Chrome("./chromedriver", options=options)
driver.get(URL)
time.sleep(2)  # ページが確実にレンダリングされるのを待つ
driver.execute_script('window.print();')