• 作成:
  • 更新:

MathJaxを含むローカルのHTMLをPNGに変換する

やりたいこと

Pythonから呼び出せる形式でローカルのMathJax(MathML)を含むHTMLファイルをpngに変換する.

  • ページはレンダリングされていなければならない
  • 全ての要素を含んでなければならない(スクロールバーがあるとダメということ)
  • 余計な余白があってはならない
  • ノイズが入ってはならない

選定技術

SeleniumとHeadless Chromeを選定しました.

参考文献: Python: Selenium + Headless Chrome で Web ページ全体のスクリーンショットを撮る - CUBE SUGAR CONTAINER

Pythonじゃなかったら puppeteer/puppeteer: Headless Chrome Node.js API の方が楽そう.

気をつけた箇所

visibility_of_element_locatedを使う

先行実装として python - How can I use selenium to record mathjax loading time - Stack Overflow がありますがこれではうまく動きません.

presence_of_element_locatedだとMathJaxのpreview版のレンダリングでwaitが終了してしまいます.

visibility_of_element_locatedなどを使いましょう.

document.documentElement.offsetHeightを使う

Seleniumの提供するwidthやheightではスクロールバーが発生してしまうので描画側の持っている情報をきちんと使う.

余白が消えてなかった

これpなどのブロック要素が単品であるとwidthがbody全体になってしまうので, 右の余白が消えないんですね.

解決方法を調べてたのですが調べてまでImageMagickの依存を避ける意義が分からなくなってきたので, 素直に依存してtrimしてもらうことにしました.

サーバサイドならともかくローカルで動かすならImageMagickを使っても問題ないので.

フロントエンド何も分からない人になってしまった. bodyにwidth: min-content;追加するのは改行が発生してしまうことがあるからやりたくないしどうしたら良いんだろうか. 普通web上だと問題は発生しないから解決策が見つからない.

文字が小さすぎた

options.add_argument('--force-device-scale-factor=5') で解決.

完成したスクリプト