Docker環境でseleniumを作動させる

## はじめに

こんにちは、Mottyです。
今回の記事では、SeleniumをDockerで動かす方法について詳しく解説します。

# selenimについて

Seleniumは、Webアプリケーションのテスト自動化やウェブスクレイピング、RPA構築などに非常に便利なツールですが、環境構築には手間がかかることあります。Dockerを使用することで、これらの課題を解決し、効率的にセットアップすることが可能です。

# Dockerについて

Dockerは、アプリケーションとその依存関係をコンテナとしてパッケージ化する技術です。このコンテナ化により、環境の一貫性が保たれ、異なるプラットフォーム間でも同じ環境で動作させることができます。本記事では、SeleniumをDocker環境でセットアップする手順をわかりやすく説明し、テスト自動化やデータ収集の作業を効率化する方法をお伝えします。

# セットアップ手順

### 1.プロジェクトフォルダの作成
docker-seleniumを作成します。
```bash
mkdir docker-seleium
```

### 2.docker-compose.ymlを作成
下記のようにdocker-compose.ymlを作成していきます。

```yml

version: '3'
services:
  selenium:
    image: selenium/standalone-chrome:129.0
    container_name: selenium
    ports:
      - 4444:4444  # Selenium サーバー
      - 7900:7900  # VNC（Seleniumの挙動を確認するためのGUI）
    shm_size: '2gb'
  
  python:
    build: ./docker
    container_name: python-app
    depends_on:
      - selenium
    volumes:
      - ./src:/app/src
    environment:
      - SELENIUM_URL=http://selenium:4444/wd/hub 

```

ローカル環境で動かすseleniumとは少し違うので、

seleniumの動作環境についてに

:::note 
dockerコンテナからseleniumを操作するときは直接webdriverをたたくのではなく、seleniumサーバーを介してコマンドをやりとりします。そのためのポートを開放する必要があります(4444)。
:::

ブラウザの閲覧方法に関して

:::note
コンテナ内は軽量化されていてGUIを動かすエンジンが搭載されていないので、コンテナ内から直接ブラウザを閲覧することができません。VNCからリモート通信して、webdriverの挙動を監視します(7900)。
:::

### フォルダを作成

seleniumは公式イメージを使用したので、
次にpython環境のインフラを整えていきます。

・srcフォルダを作成
・dockerフォルダを作成
・dockerフォルダ直下にDockerfileとrequirements.txtを作成


```Dockerfile
FROM python:3.9-slim
# 作業ディレクトリを設定
WORKDIR /app/src/

# requirements.txt をコピーして依存関係をインストール
COPY ./requirements.txt /app/src/
RUN pip install -r requirements.txt

# コンテナを終了させないためのエントリーポイント
ENTRYPOINT ["tail", "-f", "/dev/null"]
```

```requirements.txt
selenium==4.25.0
```

:::note
Dockerfileの中身のコマンドプロセスがすべて完了すると、Dockerのコンテナが終了してしまいます。そうなると、コンテナの中に入ってコードを編集することが難しくなるので、ENTRYPOINTをtail -f /dev/nullに設定することで、コンテナが常に動作し続けるようにしています。
:::

seleniumのバージョンはDocker-hubの公式イメージを参照しています。
今回、参照した内容は[こちら](https://hub.docker.com/layers/selenium/standalone-chrome/129.0/images/sha256-4aaebdcdeb97342291cf70bf289aaaebba1a6f4cf18e39080394225a4b5a2b25?context=explore)

srcフォルダ直下にpythonのメインファイルを作成

```main.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from time import sleep

# Selenium サーバー (Remote WebDriver) の設定
selenium_url = "http://selenium:4444/wd/hub"
chrome_options = Options()
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")

# ブラウザを表示するための設定
chrome_options.add_argument("--start-maximized")  # ブラウザを最大化
chrome_options.add_argument("--disable-infobars")  # 情報バーを無効化
chrome_options.add_argument("--disable-extensions")  # 拡張機能を無効化

driver = webdriver.Remote(command_executor=selenium_url, options=chrome_options)

driver.get("https://www.google.co.jp/")

driver.save_screenshot("screenshot.png")

print(driver.title)
sleep(2)
driver.quit()
```

googleのタイトルがコンソールに表示され、トップ画面のスクリーンショットが撮影できていれば、動作確認OKとしました。


# seleniumのGUIが立ち上がらない
Docker Compose設定時にも少し触れましたが、ローカル環境とは異なり、Seleniumのブラウザが立ち上がらないまま処理が実行されることに気づくでしょう。これは、軽量化されたDockerコンテナ内にはGUIを動作させるためのエンジンが存在しないためです。

そこで、VNC（Virtual Network Computing）を利用してSeleniumの動作状況を監視します。VNCを使うことで、コンテナ内で実行されているブラウザのGUIにアクセスし、実際の動作を確認できるようになります。

### 動作手順

1.localhost:7900に接続
2.「接続」をクリック
3.資格情報（パスワード）を入力(デフォルトではsecret)
4.下記のような画像が見えていたらOK

![スクリーンショット 2024-09-28 160444.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302420/722d499d-d41e-82e0-442e-6b748bb03538.png)


このブラウザにて、コンテナ内のseleniumの挙動をウォッチすることができます。

↓こんな感じ
![スクリーンショット 2024-09-28 160803.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302420/54faf4b1-4135-782a-57ed-0fc247960dbf.png)


# 最後に

ブラウザがアップデートされると、webdriverとの互換性が失われてしまい、エラーの原因となる可能性があります。
コンテナ化された環境では各々のアプリバージョンを固定できるので、セキュアな運用ができるはずです。

[Githubリポジトリはこちら](https://github.com/indpyamamoto2403/docker-selenium-standalone)