環境
Mac 11.3.1
Chromium 92.0.4512.0
ChromeDriver
Python 3.9.5
selenium 3.141.0
PyInstaller 4.3
やりたかったこと
PyInstallerで作成する 実行ファイル(.app) にChromiumとChromeDriverのバイナリを含むことで、ChromeとChromeDriverをインストールしてない環境でもダブルクリックでSeleniumでブラウザ操作を自動化することがやりたかったことです。
以下、失敗手順と妥協案です。
ChromiumとChromeDriverのダウンロード
以下のリンクからChromiumのサイトにアクセスします。
https://www.chromium.org/getting-involved/download-chromium
Head to https://commondatastorage.googleapis.com/chromium-browser-snapshots/ をクリックしてダウンロードページを開きます。
なお、最新版をEasy Point and Click for latest buildの方から取得することもできます。
しかし、そちらからだとChromeDriverを別でダウロードする必要があるのでsnapshotsの方が楽です。
希望する環境のフォルダを選びます。
私の場合はMacです。
フォルダ開くとロードに時間がかかるのでプロテインを飲みながら待ちます。
ロードが完了したら、Filterにlastと入力します。
表示されるLAST_CHANGEをクリックしてファイルをダウンロードします。
次にダウンロードしたLAST_CHANGEに書かれている数字をFileterに入力します。
表示されたフォルダを開きます。
chrome-mac.zipとchromedriver_mac64.zipをクリックしてダウンロードします。
ChromiumとChromeDriverの配置
ダウンロードしたChromiumとChromeDriverのzipを解凍します。
ChromiumとchromedriverをPythonコードのプロジェクトディレクトリに配置します。
ソース内でブラウザとドライバのパスを指定する
以下のようにAPP実行パスを考慮し、ブラウザとドライバを指定します。
import os
import sys
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# APP実行パス
try:
base_path = sys._MEIPASS
except Exception:
base_path = os.path.dirname(__file__)
# ブラウザパス
browser_path = os.path.join(base_path, "browser/Chromium.app")
# ドライバパス
driver_path = os.path.join(base_path, "browser/chromedriver")
# ブラウザ起動
chrome_options = webdriver.ChromeOptions()
chrome_options.binary_location = browser_path
driver = webdriver.Chrome(driver_path, options=chrome_options)
PyInstaller で実行ファイルを作る
PyInstaller の--add-data
オプションを使用してブラウザとドライバを含めた実行ファイルを作成します。
pyinstaller yuyuublog.py --onefile --noconsole --add-binary "./browser/chromedriver:./browser" --add-binary "./browser/Chromium.app:./browser"
エラー① ValueError: Unknown Mach-O
上記のコマンドを実行するとエラーが発生します。
ValueError: Unknown Mach-O .....
調べてみても解決策が見つからず。。。
Macだと–add-binaryがエラーになるという情報があったのでとりあえず–add-dataにして実行するとUnknown Mach-Oのエラーはなくなりました。
pyinstaller yuyuublog.py --onefile --noconsole --add-data "./browser/chromedriver:./browser" --add-data "./browser/Chromium.app:./browser"
エラー② no chrome binary
–add-dataにすることで実行ファイルは作成できました。
これをダブルクリックで実行すると、webdriver.Chrome()の箇所でエラーが発生。
Chromium.appがないと言われているみたいなんですが、原因がわからず解決しません。。。
Message: unknown error: no chrome binary at /var/folders/r7/mggt64zj6cn6yf1bgpw04rrh0000gn/T/_MEIgZDj4i/browser/Chromium.app
妥協案
どうしてもエラーを解決できなかったので、ChromiumとChromeDriverをバイナリに含めるのを諦めました。
そう、browserも一緒に配布してしまえ作戦です。
↓配布するディレクトリのイメージ
そして、Pythonコード内からパスを指定します。
さらにbinary_locationを指定するとエラーになるため、ブラウザのパス指定も削除します。
chromedriverと一緒のディレクトリにあるブラウザが勝手に認識されるっぽい?
import os
import sys
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# APP実行パス
base_path = os.path.dirname(os.path.abspath(sys.argv[0]))
# ドライバパス
driver_path = os.path.join(base_path, "browser/chromedriver")
# ブラウザ起動
chrome_options = webdriver.ChromeOptions()
driver = webdriver.Chrome(driver_path, options=chrome_options)
そして、Pyinstallを実行します。
シンプルに以下のコマンドでいきます。
pyinstaller yuyuublog.py --onefile
作成されたファイルをダブルクリックで実行します。
うごくいくはず!私は動きました。
妥協案の産物ですが、これでいくことにします。
考え方を変えれば、browser内のファイルを置き換えることで自由にChromiumのバージョンを変更できます。
むしろ便利!
まとめ
以上です。
誰かエラーの正しい解決策を教えて下さいT_T
ありがとうございました!