seleniumライブラリを含めて、pyinstallerでEXE化する
はじめに
Python環境がインストールされていない状況でも、Seleniumライブラリを含めたEXE化によって動作させる。
環境
- Windows OS : 21H2 (64bit)
- Python Version : Python 3.10.5
- Chrome : 103.0.5060.53
- Chrome Driver Version : 103.0.5060.53
プロジェクト構成
プロジェクト構成は以下のとおり。
browserフォルダーの各種ファイルは環境のC:\Program Files\Google\Chrome\Application\
から取得する。
Chrome Driver
は以下から取得する
- ブラウザーのドライバーをインストールする
project | |-browser | |-103.0.5060.53 | |-chrome.exe | |-driver | |-chromedriver.exe | |-main.py |-selenium-automation.spec
Pythonライブラリバージョン
使用ライブラリバージョンは以下のとおり。
altgraph==0.17.2 async-generator==1.10 attrs==21.4.0 certifi==2022.6.15 cffi==1.15.0 cryptography==37.0.2 future==0.18.2 h11==0.13.0 idna==3.3 outcome==1.2.0 pefile==2022.5.30 pycparser==2.21 pyinstaller==5.1 pyinstaller-hooks-contrib==2022.7 pyOpenSSL==22.0.0 PySocks==1.7.1 pywin32-ctypes==0.2.0 selenium==4.2.0 sniffio==1.2.0 sortedcontainers==2.4.0 trio==0.21.0 trio-websocket==0.9.2 urllib3==1.26.9 wsproto==1.1.0
手順
以下のコマンドを実行する。selenium-automation.specファイルが生成される
- pyinstaller main.py --onefile --noconsole --name selenium-automation
specファイルのAnalysisのdatasとhiddenimportsを編集する
- datas=[("./browser", "./browser"), ("./driver", "./driver")],
- hiddenimports=["selenium"],
- EXE化コマンドで実行
--clean
を必ず指定する。前回ファイルが影響することがある- pyinstaller --clean selenium-automation.spec
補足
specファイル
specファイルにおいて、hiddenimportsを指定することでライブラリを同梱できる
sys._MEIPASSとは
https://stackoverflow.com/questions/22472124/what-is-sys-meipass-in-python
Cleanな環境でexeファイルを生成すること
余計なPythonライブラリを含めない。最小限の構成で作成する。仮想環境で一度すべてのPythonライブラリをuninstallしてから作業するとよい
Pythonライブラリ取得]
- pip freeze > requirement.txt
Pythonライブラリ全削除]
- pip uninstall -r requirement.txt
手動のpip installで復旧
- 1つずつ復旧する
ソースコード
main.py
ファイルの内容を以下に記載した。
proxyがある場合は、proxyを通す設定が必要になります。 proxyを通して、実行する場合は以下のコメントを外してください。
# PROXY_AUTH = '{userid}:{password}' # set_proxy_setting(PROXY) # options.add_argument(f"--proxy-server={PROXY}") # options.add_argument(f"--proxy-auth={PROXY_AUTH}")
# main.py import os import sys from selenium import webdriver from selenium.webdriver.chrome.options import Options import time def set_proxy_setting(proxy_server: str): # スクリプト内で環境変数をセットする os.environ["http_proxy"] = proxy_server os.environ["https_proxy"] = proxy_server os.environ['no_proxy'] = "127.0.0.1,localhost" os.environ['NO_PROXY'] = "127.0.0.1,localhost" def resource_path(relative_path): try: base_path = sys._MEIPASS except Exception: base_path = os.path.dirname(__file__) return os.path.join(base_path, relative_path) def main(): browser_full_path = resource_path("./browser/chrome.exe") chrome_driver_full_path = resource_path("./driver/chromedriver.exe") # WebDriver のオプションを設定する options = Options() options.binary_location = browser_full_path options.add_argument("start-maximized") options.add_argument("-disable-gpu") options.add_argument("--ignore-certificate-errors") # Selenium Chrome Proxy の設定 # PROXY Example : "http://192.168.0.100:8080" # PROXY = "http://192.168.0.100:8080" # PROXY_AUTH = '{userid}:{password}' # set_proxy_setting(PROXY) # options.add_argument(f"--proxy-server={PROXY}") # options.add_argument(f"--proxy-auth={PROXY_AUTH}") driver = webdriver.Chrome( executable_path=chrome_driver_full_path, chrome_options=options) # スクレイピングを実行する URL = "https://stackoverflow.com/" driver.get(URL) # 3秒ウェイトする time.sleep(3) driver.close() driver.quit() if __name__ == "__main__": main()
specファイル
`selenium-automation.spec'の内容を以下に記載した。
# -*- mode: python ; coding: utf-8 -*- block_cipher = None a = Analysis( ['main.py'], pathex=[], binaries=[], datas=[("./browser", "./browser"), ("./driver", "./driver")], hiddenimports=["selenium"], hookspath=[], hooksconfig={}, runtime_hooks=[], excludes=[], win_no_prefer_redirects=False, win_private_assemblies=False, cipher=block_cipher, noarchive=False, ) pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE( pyz, a.scripts, a.binaries, a.zipfiles, a.datas, [], name='selenium-automation', debug=False, bootloader_ignore_signals=False, strip=False, upx=True, upx_exclude=[], runtime_tmpdir=None, console=False, disable_windowed_traceback=False, argv_emulation=False, target_arch=None, codesign_identity=None, entitlements_file=None, )
参考リンク
SeleniumをEXEで動かす
specファイルの取り扱いについて詳細に記載されている