Python3+SeleniumでWEBサイトのスクリーンショットを撮る

## 実行に必要なモジュールのインストール
### Seleniumのインストール
```
#Windowsの場合
pip install selenium
#Macの場合
pip3 install selenium
```
## ChromeDriverのインストールとPATHを通す方法
WEB上に掲載されているSeleniumを使用したプログラムがエラーを吐くという場合、
ソースコードの問題というより、このChromeDriverのインストールができていなかったり
PATHが通っていないことで下記のエラーが出ているということが多いのではないかな？と思います

```
Traceback (most recent call last):
  File "c:/Users/User/Desktop/sample.py", line 7, in <module>
    driver = webdriver.Chrome(options=options)
  File "C:\Users\User\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\chrome\webdriver.py", line 73, in __init__
    self.service.start()
  File "C:\Users\User\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\common\service.py", line 81, in start
    raise WebDriverException(
selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH.
    Please see https://sites.google.com/a/chromium.org/chromedriver/home
```

上記エラーへの対策は私調べでは3通りあります。

- ChromeDriverをインストールした上でパスを通す
- webdriver.Chrome()の記述内にパスを直打ちする
- importを追加してパスを通す

おすすめは1つ目の**ChromeDriverをインストールした上でパスを通す**ですが
この記事ではタイトルの内容の記述に早く移りたいので、
**一番簡単に対応可能な3つ目のimportを追加してパスを通すを紹介します**。
他の方法で対策したいという方は、WindowsなのかMacなのかによってもやり方が違うので
ChromeDriverとOSのキーワードで検索をしてみてください。

## importを追加してパスを通す方法
### ChromeDriverのインストール

```
#Windowsの場合
pip install chromedriver-binary
#Macの場合
pip3 install chromedriver-binary
```

### importの記述

```
import chromedriver_binary
```

## ソースコード

下記ソースコード内には importを追加してパスを通す方法で紹介した
importの記述はありませんので必要であれば追記して実行してみてください。

```
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

url = 'https://www.oanda.jp/lab-education/oanda_lab/oanda_rab/currency_power_balance/'
options = Options()
options.add_argument('--headless')
driver = webdriver.Chrome(options=options)
driver.get(url)

page_width = driver.execute_script('return document.body.scrollWidth')
page_height = driver.execute_script('return document.body.scrollHeight')
print('page_width', page_width, sep=':')
print('page_height', page_height, sep=':')
driver.set_window_size(page_width, page_height)

driver.save_screenshot('screenshot.png')
driver.close()
driver.quit()
exit()
```

## エラーが発生した場合

Seleniumをインストールした。ChromeDriverもインストールした。importも書いた。
でもエラーになったという場合、**下記のエラーと同じエラーが発生した場合の対処を追記しておきます**。

```
DevTools listening on ws://127.0.0.1:62988/devtools/browser/a9ef2367-49e5-4405-b33f-2782f0eaad42
Traceback (most recent call last):
  File "sample.py", line 9, in <module>
    driver = webdriver.Chrome(options=options)
  File "C:\Users\User\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\chrome\webdriver.py", line 76, in __init__
    RemoteWebDriver.__init__(
  File "C:\Users\User\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 157, in 
__init__
  File "C:\Users\User\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 252, in 
start_session
    response = self.execute(Command.NEW_SESSION, parameters)
  File "C:\Users\User\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in 
execute
    self.error_handler.check_response(response)
  File "C:\Users\User\AppData\Local\Programs\Python\Python38\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242,
    in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.SessionNotCreatedException:
    Message: session not created: This version of ChromeDriver only supports Chrome version 84
```

このエラーは、エラーメッセージ内には ChromeDriverのバージョンが84じゃないとサポートしないと書いてありますが
実際は**インストール済みのChromeのバージョンとChromeDriverの不整合によって発生するエラー**です。

**今インストールされているChromeブラウザのバージョンを確認し、
そのインストールするChromeDriverをChromeブラウザのバージョンと同じか1つ前のバージョンにすることで改善します**。

Chromeブラウザの設定 > ヘルプ > Google Chromeについて を押下すると、Chromeブラウザのバージョンが確認できます。
![pic1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242547/9c7585a6-5b11-fa8a-6a8a-fbd88150fd0b.png)
画面では、バージョンが 83.0.4103.116 なので、インストールのコマンドにバージョンを追記して実行します。

```
# Windowsの場合
pip install chromedriver-binary==83.0.4103.116
# Macの場合
pip3 install chromedriver-binary==83.0.4103.116
```

一致するバージョンのChromeDriverがあった場合、対象のバージョンのChromeDriverがインストールされて完了ですが
一致するバージョンのChromeDriverがない場合、以下のようなエラーメッセージが表示されます。

```
Collecting chromedriver-binary==83.0.4103.116
  ERROR: Could not find a version that satisfies the requirement chromedriver-binary==83.0.4103.116
  (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, 2.40.1, 2.41.0, 2.42.0, 2.43.0, 2.44.0, 2.45.0, 2.46.0, 70.0.3538.16.0,
                  70.0.3538.67.0, 70.0.3538.97.0, 71.0.3578.30.0, 71.0.3578.33.0, 71.0.3578.80.0,
                  71.0.3578.137.0, 72.0.3626.7.0, 72.0.3626.69.0, 73.0.3683.20.0, 73.0.3683.68.0, 
                  74.0.3729.6.0, 75.0.3770.8.0, 75.0.3770.90.0, 75.0.3770.140.0, 76.0.3809.12.0,
                  76.0.3809.25.0, 76.0.3809.68.0, 76.0.3809.126.0, 77.0.3865.10.0, 77.0.3865.40.0,
                  78.0.3904.11.0, 78.0.3904.70.0, 78.0.3904.105.0, 79.0.3945.16.0, 79.0.3945.36.0,
                  80.0.3987.16.0, 80.0.3987.106.0, 81.0.4044.20.0, 81.0.4044.69.0, 81.0.4044.138.0,
                  83.0.4103.14.0, 83.0.4103.39.0, 84.0.4147.30.0)
ERROR: No matching distribution found for chromedriver-binary==83.0.4103.116
```

インストールするChromeDriverをChromeブラウザのバージョンの1つ前のバージョンにすることで改善すると
上で記述しているので、**この一覧から1つ前のバージョンであろうものを探します**。

>83.0.4103.39.0

上記のバージョンが1つ前のバージョンに当たるので、このバージョンのChromeDriverをインストールします。

```
# Windowsの場合
pip install chromedriver-binary==83.0.4103.39.0
# Macの場合
pip3 install chromedriver-binary==83.0.4103.39.0
```

インストールが完了したら、再度スクリーンショットを撮るプログラムを実行してみると

```
PS C:\Users\User\Desktop> python sample.py

DevTools listening on ws://127.0.0.1:63400/devtools/browser/70375409-a059-4976-b851-176545080407
page_width:912
page_height:1963
```

こんなメッセージが表示され、実行した場所に screenshot.png が出力されているはずです。
![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242547/f7d28e0f-0f2d-1779-2e24-4bd98f390618.png)