LoginSignup
11
7

【Python】MacでSeleniumを操作する事始め

Last updated at Posted at 2022-04-03

はじめに

Excelでwebブラウザの操作を自動化する最小機能のみ実装したフレームワークの「TinySeleniumVBA」があります。
これは今のところActiveXを使用しているため、Windows専用になっています。ActiveXの部分を取り除き代替部分をVBA-toolsライブラリー群を使えば、Mac上のExcelで動作するかもと取り組みました。
VBA-toolsを用いてWindows上では動作するようになったのですが、残念ながらMacではエラーで動作しませんでした。

何が原因なのか分からないため、MacにSeleniumをPythonで動かしてみようと思った次第です。
簡単かと思ったら結構ハマったので記事にしてみました。

【2023/06/06追記】
自記事は少し古いので、この記事を参考に新しいバージョン(Selenium 4.9.1)で動くように対応とのこと。

【2023/10/14追記】
Selenium 4.6以降から、ドライバのインストールツールである Selenium Manager が操作対象となるウェブブラウザのバージョンも考慮してドライバをインストールしてくれるようになっています。

環境構築

  • Mac Book Pro(2.3 GHz 8コアIntel Core i9) Monterey 12.2.1
  • Google Chrome Ver.100.0.4896.60(Official Build)
  • Python 2.7.18 と Python 3.9.4 共存した状態

Seleniumのインストール

pip3 install selenium

今回は、selenium ver 4.1.3 が入りました。

pipとpip3の違い

Python 2系とPython 3系が共存する環境では、pipはPython2、pip3はPython3にインストールされます。
どちらか一方であれば、pipを使用すればいいです。

Google Chromeドライバのインストール

右端上部にある「⋮」のメニュー → ヘルプ → Google Chromeについて

(例)
Chrome は最新の状態です
バージョン: 100.0.4896.60(Official Build) (x86_64)

pip3 install chromedriver-binary-auto

バージョンを自動判断してインストールされることを期待するも、エラーでインストールできませんでした。

バージョンを指定する

バージョンを入れないまま実行するとバージョンの一覧が表示されます。

pip3 install chromedriver-binary==
ERROR: Could not find a version that satisfies the requirement chromedriver-binary== 
(from versions: 2.29.1, 2.31.1, 2.33.1, 2.34.0, 2.35.0, 2.35.1, 2.36.0, 2.37.0, 2.38.0, 2.39.0,
                                       ⋮
 99.0.4844.17.0, 99.0.4844.35.0, 99.0.4844.51.0, 100.0.4896.20.0, 100.0.4896.60.0, 101.0.4951.15.0)
ERROR: No matching distribution found for chromedriver-binary==

確認したChromeのバージョンと一致するものを指定します。
ChromeDriverのバージョンはそこまで厳密に合わせる必要はありません。
以下公式の「バージョンの選び方」説明ページで、最後の桁はあっていなくても良いと書かれています。一番番号が近いものを使いましょう。

Each version of ChromeDriver supports Chrome with matching major, minor, and build version numbers. For example, ChromeDriver 73.0.3683.20 supports all Chrome versions that start with 73.0.3683.
↓翻訳
ChromeDriverの各バージョンは、メジャー、マイナー、ビルドの各バージョン番号が一致するChromeに対応しています。例えば、ChromeDriver 73.0.3683.20は73.0.3683で始まるすべてのChromeのバージョンをサポートします。
https://chromedriver.chromium.org/downloads/version-selection


# ChromeDriverのインストール
pip3 install chromedriver-binary==「確認したChromeのバージョン」
# 自分の環境だとこんな感じ
pip3 install chromedriver-binary==100.0.4896.60.0

Collecting chromedriver-binary==100.0.4896.60.0
  Using cached chromedriver-binary-100.0.4896.60.0.tar.gz (4.9 kB)
  Preparing metadata (setup.py) ... done
Using legacy 'setup.py install' for chromedriver-binary, since package 'wheel' is not installed.
Installing collected packages: chromedriver-binary
  Running setup.py install for chromedriver-binary ... done
Successfully installed chromedriver-binary-100.0.4896.60.0

【2023/11/24追記】
久しぶりに、chromedriverをインストール。
現在のバージョンは、119.0.6045.159 ですが、No matching となったので、119.0.6045.105.0を指定してインストールするも、エラーが発生

% pip install chromedriver-binary==119.0.6045.159
ERROR: No matching distribution found for chromedriver-binary==119.0.6045.159

% pip install chromedriver-binary==119.0.6045.105.0

error: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1123)>

下記サイトを参考にしてみた。

# こっちでは駄目だった。
% pip install --upgrade certifi

# こっちなら成功 ※ Pythonのバージョンを合わせることが必要!
% open /Applications/Python\3.9/Install\Certificates.command  
% pip install chromedriver-binary==119.0.6045.105.0
Successfully installed chromedriver-binary-119.0.6045.105.0

インストールの場所は、pip show chromedriver-binary のLocationで分かる。
更に配下のchromedriver_binary/chromedriver
※ 間の -_ になっている。

% pip show chromedriver-binary             
Name: chromedriver-binary
Version: 119.0.6045.105.0
Summary: Installer for chromedriver.
Home-page: https://github.com/danielkaiser/python-chromedriver-binary
Author: Daniel Kaiser
Author-email: daniel.kaiser94@gmail.com
License: MIT
Location: /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages
Requires: 
Required-by:

ダウンロードサイトから取得してインストール

それでもpipでインストールできない場合、ChromeDriverのダウンロードサイトから近いバージョンのものをダウンロードします。

その場合、/usr/local/bin/フォルダにchromedriverを入れました。

実行する

python3 selenium-test.py

実行時に「開発元を検証できないため開けません」が表示されたら、下記サイトを参考にしてください。

ソースコード

Chromeを起動して、Google検索で"Selenium"を検索する。
Selenium 4で「DeprecationWarning」が出る場合の対策

今回はTinySeleniumVBAでも使用できるように、ChromeDriverは/usr/local/bin/フォルダに配置しました。pipコマンドでインストールした場合、executable_pathの指定は不要です。

# ブラウザを開く
chrome_service = fs.Service(executable_path='/usr/local/bin/chromedriver')
 ↓
import chromedriver_binary
# ブラウザを開く
chrome_service = fs.Service()
selenium-test.py
# coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep
from selenium.webdriver.chrome import service as fs

# ブラウザを開く
chrome_service = fs.Service(executable_path='/usr/local/bin/chromedriver')
driver = webdriver.Chrome(service=chrome_service)
# Googleの検索TOP画面を開く
driver.get("https://www.google.co.jp/")

# 検索語として「selenium」と入力し、Enterキーを押す。
search = driver.find_element_by_name('q') 
search.send_keys("selenium")
search.send_keys(Keys.ENTER)

# 5秒間待機してみる。
sleep(5)
# ブラウザを終了する。
driver.close()

結果

スクリーンショット 2022-04-03 23.24.53.png

プロセスが残る

driver.close()では、プロセスが残ったままになります。何度も実行すると大量に残ったまま。

ps aux | grep chromedriver                      
yaju         88651   0.0  0.1 67767416  10180 s000  S    11:24PM   0:00.12 /usr/local/bin/chromedriver --port=56927
yaju         88589   0.0  0.1 67776632  10492 s000  S    11:24PM   0:00.12 /usr/local/bin/chromedriver --port=56893
yaju         88533   0.0  0.1 67767416  10640 s000  S    11:24PM   0:00.12 /usr/local/bin/chromedriver --port=56863
yaju         87247   0.0  0.1 67767416   9316 s000  S    11:14PM   0:00.14 /usr/local/bin/chromedriver --port=56769
yaju         47776   0.0  0.0 67390920   3620   ??  S     5:21PM   0:00.37 /usr/local/bin/chromedriver
yaju         89272   0.0  0.0 34132100    916 s000  S+   11:29PM   0:00.00 grep chromedriver

killall chromedriver でプロセスを全て終了します。

killall chromedriver    
ps aux | grep chromedriver                      
yaju         90473   0.0  0.0 34122884    880 s000  S+   11:38PM   0:00.00 grep chromedriver

quit()を使用する

close()は現在のウィンドウの終了で、quit()は全てのウインドウとドライバーの終了という違いがあるが、ChromeDriverではquit()の実装がService.stop()も呼ぶようになっている。

with構文を使う

Webdriverの実装を見てみると、__exit__でquit()が呼ばれているのでwith構文を使えば同じことができる。

class WebDriver(BaseWebDriver):
    def __exit__(self, *args):
        self.quit()

with構文で書き換えてみる。

selenium-test.py
# coding:utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from time import sleep
from selenium.webdriver.chrome import service as fs
#import chromedriver_binary

# ブラウザを開く。
chrome_service = fs.Service(executable_path='/usr/local/bin/chromedriver')
with webdriver.Chrome(service=chrome_service) as driver:
   # Googleの検索TOP画面を開く。
   driver.get("https://www.google.co.jp/")

   # 検索語として「selenium」と入力し、Enterキーを押す。
   search = driver.find_element_by_name('q') 
   search.send_keys("selenium")
   search.send_keys(Keys.ENTER)

   # 5秒間待機してみる。
   sleep(5)

ブラウザを開いたまま処理を終了する

close()やquit()は使わず、chromeを開いたままプロセスを終了させます。

from selenium import webdriver
import os
import signal

driver = webdriver.Chrome(service=chrome_service)

try:
    # ~いろいろな処理~
finally:
    os.kill(driver.service.process.pid,signal.SIGTERM)

最後に

SeleniumをPythonで動かすことができました。
MacでTinySeleniumVBAが動作しないのは、下記サイトで仕組みを知ることで原因が分かりました。

MacではExcelのバージョンによってShellコマンドを使用して、chromedriverを起動することが出来なくなっていたためでした。調査した結果、AppleScriptTask コマンドを使用しAppleScript スクリプト側でchromedriverが起動させることで解決できました。

11
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7