nprogram’s blog

気ままに、プログラミングのトピックについて書いていきます

seleniumライブラリを含めて、pyinstallerでEXE化する

はじめに

Python環境がインストールされていない状況でも、Seleniumライブラリを含めたEXE化によって動作させる。

環境

プロジェクト構成

プロジェクト構成は以下のとおり。

 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

手順

  1. 以下のコマンドを実行する。selenium-automation.specファイルが生成される

    • pyinstaller main.py --onefile --noconsole --name selenium-automation
  2. specファイルのAnalysisのdatasとhiddenimportsを編集する

    • datas=[("./browser", "./browser"), ("./driver", "./driver")],
    • hiddenimports=["selenium"],
  3. 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してから作業するとよい

  1. Pythonライブラリ取得]

    • pip freeze > requirement.txt
  2. Pythonライブラリ全削除]

    • pip uninstall -r requirement.txt
  3. 手動の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,
)

参考リンク

Pythhon Seleniumトピック記録

本記事について

Python + Seleniumのトピックを記録していきます。

Chromeドライバーインストールを自動化する

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)

PythonでOutlookからメール送信

本記事について

Pythonを用いたOutlookからメール送信のソースコードになります。

以下のパッケージのインストールが必要になります。 pip install pywin32

mail.BodyFormatの値を切り替えることで、 どの形式でメールを送信するか選択できます。 (テキスト形式、HTML形式、リッチテキスト形式)

import datetime
import pathlib
import win32com.client

def send_mail(FAMILY_NAME : str, full_name : str):
    outlook = win32com.client.Dispatch("Outlook.Application")
    mail = outlook.CreateItem(0)
    # メールフォーマット:1 テキスト, 2 HTML, 3 リッチテキスト
    mail.BodyFormat = 2 # HTML
    mail.to = 'xxxx@exc.epson.co.jp'

    cc_list = ['xxxx@exc.epson.co.jp'
               'xxxx@exc.epson.co.jp',
               'xxxx@exc.epson.co.jp',
    ]

    mail.cc = ';'.join(cc_list)
    mail.bcc = ''
    dt_now = datetime.datetime.now()
    today = dt_now.strftime('%Y/%m/%d')
    mail.subject = '【タイトル】' + ' ' + full_name + ' ' + today
    mail.bodyFormat = 2

    text_file_path = "data\src\message.txt"
    f = open(text_file_path, 'r', encoding='UTF-8')
    text_message = f.read()
    f.close()
    mail.body = text_message.replace(r"{{FAMILY_NAME}}", FAMILY_NAME)

    # 出来上がったメールを確認します。
    mail.Display(True)

FAMILY_NAME = 'FAMILY_NAME'
FIRST_NAME = 'FIRST_NAME'
FULLNAME = FAMILY_NAME + FIRST_NAME

send_mail(FAMILY_NAME, FULLNAME)

Python_Herokuへのデプロイ方法 (LINE通知編)

はじめに

以下のファイルをherokuで使用する場合は、エンコードの選択は必ずUTF-8(BOM無し)を選択してください。

  • ‘Procfile‘
  • ‘requirement.txt‘
  • ‘runtime.txt‘

作成方法

(1) herokuへログインする heroku login

(2) アプリを作成する heroku apps:create line-stock-price

(3) Build Packを追加する

  • heroku buildpacks:add heroku/python -a <アプリ名>
  • heroku buildpacks:add https://github.com/heroku/heroku-buildpack-google-chrome -a <アプリ名>
  • heroku buildpacks:add https://github.com/heroku/heroku-buildpack-chromedriver -a <アプリ名>

(4) requirements.txtを作成する * pip freeze > requirements.txt

コマンド一覧

  • Gitの初期ファイル作成

    • git init
  • ローカルリポジトリに紐づくリモートリポジトリを設定

    • heroku git:remote -a <アプリ名>
  • 変更したファイルをインデックスに登録

    • git add .
  • コミットを実施する

    • git commit -m "commit_message"
  • リモートリポジトリへのプッシュを実施する

    • git push heroku master
  • gitログ確認

    • git log
  • git status確認

    • git status
  • heroku上でプログラム実行

    • heroku run python main.py

Gitコマンドまとめ

  • ローカルの特定のファイルをを元に戻す
    • git checkout <filename>
  • ローカルの全てのファイルを元に戻す
    • git checkout .
  • ローカルのbranch一覧確認コマンド
    • 'git branch'

以下のサイトが参考になります。

Python】herokuへデプロイしLINE通知する方法│初心者 / https://nkmrdai.com/python-heroku-linenotify/

qiita.com

テストエンジニア技術調査

はじめに

ノンコーディング技術調査をはじめとるするをまとめてみました。

Amazon Honeycode

ノンコーディングでWebアプリを構築できるAmazon Honeycodeなど、AWSが新サービスを紹介

https://it.impress.co.jp/articles/-/20134

ノーコード開発ツールおすすめ13選 プログラミングなしでアプリやWebサイトを作ろう

https://tech-camp.in/note/technology/92173/

テストの未来 テストエンジニアの「これまで」と「これから」を考える

テストの未来 テストエンジニアの「これまで」と「これから」を考える|実績・強み|ソフトウェアテスト・第三者検証のベリサーブ

参考

【ノーコードの衝撃】IT業界が根底から変わる、日本人の知らないノーコードアプリの進化