プログラミング

【Python・Selenium】実行ファイルにChromiumとChromeDriverを含められなかった【失敗談・妥協案】

こんにちは ゆゆう(@yuyuublog) です。

PyInstallerを利用して、Pythonで作ったSelenium実行プログラムにChromiumとChromeDriverを含みたいと考えました。

色々試しましたがうまくいきませんでした。

誰か助けてT_T という失敗談と妥協案による解決策です。

環境

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.zipchromedriver_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

アイコン名を入力

ありがとうございました!

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA