はじめに
メールの受信を自動化する方法を調査しています。
自動化したいメーラーは以下の2つです。
Gmailの受信を自動化する方法について調査します。
https://docs.microsoft.com/ja-jp/power-automate/desktop-flows/install
本記事では、seleniumライブラリを含めて、pyinstallerでEXE化する (Selenium4.Xで記載)。
なお、EXEにはChrome DriverやChromeブラウザーは含めない。
Chrome Driverはwebdriver-managerライブラリによってChromeブラウザーバージョンにあったものを取得させる。
import os from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager import time def set_os_proxy_setting(proxy_server : str): # スクリプト内で環境変数をセットする os.environ["http_proxy"] = proxy_server os.environ["https_proxy"] = proxy_server os.environ["no_proxy"] = 'localhost,127.0.0.1' def main(): # WebDriver のオプションを設定する # https://qiita.com/skimhiro/items/de501f45607d6a09cde5 options = webdriver.ChromeOptions() options.add_argument("--no-sandbox") options.add_argument("--disable-gpu") options.add_argument("--ignore-certificate-errors") options.add_argument("--start-maximized") options.add_experimental_option('excludeSwitches', ['enable-logging']) # Selenium Chrome Proxy の設定 # PROXY_IP_ADDRESS_AND_PORT = "http://192.168.0.100:8080" # set_os_proxy_setting(PROXY_IP_ADDRESS_AND_PORT) # PROXY_AUTH = '{userid}:{password}' # options.add_argument(f"--proxy-server={PROXY_IP_ADDRESS_AND_PORT}") # options.add_argument(f"--proxy-auth={PROXY_AUTH}") # driverを生成する service=Service(ChromeDriverManager().install()) driver = webdriver.Chrome(service=service, options=options) # スクレイピングを実行する driver.get("https://qiita.com/") time.sleep(3) driver.close() driver.quit() if __name__ == "__main__": main()
# -*- mode: python ; coding: utf-8 -*- block_cipher = None a = Analysis( ['main.py'], pathex=[], binaries=[], datas=[], hiddenimports=["selenium", "webdriver-manager"], 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, )
Python環境がインストールされていない状況でも、Seleniumライブラリを含めたEXE化によって動作させる。
プロジェクト構成は以下のとおり。
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
使用ライブラリバージョンは以下のとおり。
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ファイルが生成される
specファイルのAnalysisのdatasとhiddenimportsを編集する
--clean
を必ず指定する。前回ファイルが影響することがあるspecファイルにおいて、hiddenimportsを指定することでライブラリを同梱できる
https://stackoverflow.com/questions/22472124/what-is-sys-meipass-in-python
余計なPythonライブラリを含めない。最小限の構成で作成する。仮想環境で一度すべてのPythonライブラリをuninstallしてから作業するとよい
Pythonライブラリ取得]
Pythonライブラリ全削除]
手動のpip installで復旧
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()
`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ファイルの取り扱いについて詳細に記載されている
openpyxl による Excelファイル操作方法のまとめ https://gammasoft.jp/support/how-to-use-openpyxl-for-excel-file/
Python + Seleniumのトピックを記録していきます。
Chromeドライバーインストールを自動化する方法です。 これにより、Chrome VersionやChrome Driverの実行ファイルパスを気にしなくて済みます。
from selenium import webdriver from webdriver_manager.chrome import ChromeDriverManager driver = webdriver.Chrome(ChromeDriverManager().install()) # "任意のURL"を指定 url_path = "https://www.google.co.jp/" driver.get(url_path)
スクロールバーを操作しないとデータが生成されない場合に以下のコードが役に立ちます
import time from selenium import webdriver from webdriver_manager.chrome import ChromeDriverManager def scroll_to_bottom(driver): old_position = 0 new_position = None while new_position != old_position: # Get old scroll position old_position = driver.execute_script( ("return (window.pageYOffset !== undefined) ?" " window.pageYOffset : (document.documentElement ||" " document.body.parentNode || document.body);")) # Sleep and Scroll time.sleep(1) driver.execute_script(( "var scrollingElement = (document.scrollingElement ||" " document.body);scrollingElement.scrollTop =" " scrollingElement.scrollHeight;")) # Get new position new_position = driver.execute_script( ("return (window.pageYOffset !== undefined) ?" " window.pageYOffset : (document.documentElement ||" " document.body.parentNode || document.body);")) driver = webdriver.Chrome(ChromeDriverManager().install()) # "任意のURL"を指定 url_path = "https://apps.apple.com/jp/app/yamap-%E3%83%A4%E3%83%9E%E3%83%83-%E3%83%97-%E7%99%BB%E5%B1%B1%E5%9C%B0%E5%9B%B3-%E5%B1%B1%E7%99%BB%E3%82%8Agps%E3%83%8A%E3%83%93/id558780450#see-all/reviews" driver.get(url_path) time.sleep(2) scroll_to_bottom(driver)