【PyAutoGUI】HYPER SBIからマザーズ指数のcsvを自動取得する

#0.はじめに

株価指数を自動で落とせるところないかなぁ～なんて探しましたが、無料の場合API含めても**全て網羅**されているのが[investing.com](https://jp.investing.com/)くらいしかなかったです。

でも実はSBI証券等の証券会社ツール経由だとこれらを簡単に取得できるので、最近巷でよく耳にすることが増えた`PyAutoGUI`というのを使ってcsvの保存を練習兼ねて自動化してみました。

この技術を使えば、株以外にも普段の業務や提携作業等の自動化への応用できると思うので、株やってない方でも軽い気持ちで見ていってください。


* 動作環境
 * OS : Windows10 pro
 * Python : 3.8.3// Miniconda 4.9.1
 * PyAutoGUI : 0.9.52
 * HyperSBI  Ver.2.5
 * jupyter notebook
 * 作業日は「2021/6/13」時点なので注意。今後市場再編があるので・・


#1.PyAutoGUIの基礎

基本的には以下サイトに書いてありますが、本記事でもその中からいくつか紹介します
他にも便利な機能(キャプチャや画像検索等)あるので、気になった方は調べてみてください。

https://pyautogui.readthedocs.io/en/latest/mouse.html

##1-1.マウス位置取得と画面の基本

まずは基礎中の基礎。色んな位置にマウスを動かしながら試してみると何となくわかってくる。
なおpyautoguiはpipでインストール可能

```Python:
#!pip install pyautogui
import pyautogui

#まずは現在のマウスカーソルの位置を出力
print(pyautogui.position())
#メイン画面のサイズを取得 ※マルチモニタの場合はメイン設定のディスプレイが基準になる
print(pyautogui.size())
```

```:実行結果
Point(x=755, y=826) ※今の位置なので数値は参考程度に

Size(width=1920, height=1080) ※使用ディスプレイで結果は変わります
```


##1-2.マウス操作

次にマウスがかかわる操作からいくつか紹介。


```Python:
#座標を指定
x,y = 0,0
"""
以下試す時は1個ずつお願いします
様々なオプション等もありますが、ここでは省略してます
"""
#マウスカーソルを指定座標まで移動
pyautogui.moveTo(x, y)
#マウスカーソルを指定座標まで移動させた後に1回だけ左クリック
pyautogui.click(x, y, clicks=1, button='left') 
#マウスカーソルを指定座標まで移動させた後にダブルクリック
pyautogui.doubleClick(x, y)
#マウスカーソルを現在位置から指定位置までドラッグ
pyautogui.dragTo(x, y)
```

##1-3.キーボード操作

詳細は先程のドキュメントサイトを見るか、ほかの方の記事を見てください。
ここではよく使うものだけ紹介します。

```Python:
pyautogui.press('enter') #Enterキーを押す
pyautogui.press("left", presses=2) #矢印キーの左を2回押す
pyautogui.keyDown('ctrl') #ctrlキーを押し続ける
pyautogui.keyUp('ctrl') #ctrlキーを押し続けるのを解除
pyautogui.hotkey('ctrl','s') #hotkeyで2個同時押し
pyautogui.typewrite('aiueo') #キーボード文字を連続入力する
```

#2.(前準備)ユーザーアカウント制御の警告を停止

「よし、これでHyprSBIなんて楽勝だぜ！」と思って挑むと全く入力を受け付けてくれないことに気づきます。なぜなら**HyperSBIにはユーザーアカウント制御がかかっており、これをPyAutoGUIで操作できない**からです。
以下アイコンを見てみると、右下にセキュリティマークがついていることに気づきます。これがそのユーザーアカウント制御なのです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/53c32284-0cc9-de65-65e7-3ac11a92d498.png" width=50%>


これを無効化するには、ユーザーアアカウント制御設定を「通知しない」にすればいいんですが、セキュリティの観点からよろしくありません。よって、このアプリだけ対応します。

##2-1.プロパティのショートカットリンク先をコピー

デスクトップにHyperSBIのショートカットをまず用意します。
右クリックのプロパティから「リンク先」をコピー

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/28bc9fa9-22c6-db0b-2ec5-8a321fdbdb4e.png" width=50%>

##2-2.タスクスケジューラーを起動し、タスク名称を設定

全般タブの名前を適当につける
※今回はHyperSbiNoUacとしてます

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/36f7a329-cd9a-50f2-4d56-d4327ff0303e.png" width=80%>

##2-3.操作タブからコピーしたリンク先をスクリプト指定
2-1で取得したリンク先をプログラム/スクリプトの個所に張り付ける　
※前後のダブルクオテーションも必要！
終わったらタスクとして登録する(プロパティ画面でOKを押す)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/d915502d-d835-4ed6-4f46-c3e02c119502.png" width=70%>

##2-4.ショートカットのリンク先を変更する
2-1と同じショートカットのプロパティを開き、リンク先を以下のように変更してOKを押すと、セキュリティマークが消えている！

`C:\Windows\System32\schtasks.exe /run /tn HyperSbiNoUac`
※最後の「HyperSbiNoUac」は設定した名前、schtasks.exe /run /tnでタスク実行という意味

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/a29d84f8-bac2-b55a-aa90-cd5a2234afa6.png" width=70%>

これで準備OKである。実際にクリックしてユーザーアカウント制御画面が出ないことが確認できると思う。
このショートカットをデスクトップのわかりやすいところに配置しておきましょう。


#3.HyperSBIから株価指数のcsvを自動的に取得する

**今回はjupyter Notebookで実行するのだが、「管理者権限で実行」する必要がある**為、コマンドプロンプトを「管理者として実行」した後に、jupyter notebookと打ち込んで起動すればいい。
私はめんどいので毎回batファイル経由でjupyterを起動しているのだが、その場合はbatのショートカットを作り、ショートカットプロパティから「管理者として実行」を設定するだけでいい

## 3-1.管理者権限が付与されているか確認する

jupyterで以下コマンドをたたき、1と出力されれば管理者権限が付与。0なら付与されていない。
まずはここで1になることを確認すること。
**もし0のまま進めると、最初のログイン画面でログインボタンが押せないので注意！**

```Python:
import ctypes

print(ctypes.windll.shell32.IsUserAnAdmin())
```

```:実行結果
1
```

## 3-2.最初のログイン画面における注意点

アイコンクリックし、アプリにログインする画面ですが、ユーザネームとPASSを保存しておかないと、本解説のような動作が出来ないので注意！
※いちいち打つこともできるが、面倒なので・・

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/f24fad81-98f0-bba8-7e8d-4dfa75cc5d99.png" width=60%>

また、ここで触れておくが以下プログラムのマウスクリック箇所は例えばこのログインの場合、実際にログインボタンの個所へマウスを持って行って、`print(pyautogui.position())`とやれば調べられるのでご自身の環境で調べたうえで適宜置き換えてみてほしい


## 3-3.プログラム全体

何やってるか？はコメントに書いてあるので参照ください。
また、次の「4.起動中のイメージ」でログイン後の部分をＧＩＦ漫画にしてるのでイメージはそっちでつかんでください。

**注意点**
**<font color="Red">・以下はPC環境や配置場所によって変わるので、数字等はあてになりません。あくまで操作の流れだけを参考にしてください</font>**
・また、カレンダーで2000年2月を選んでますが、マザーズは「2003年からのデータしかない」ので適当にやっているだけです
・HyperSBIで取得できるのは20年前までです。よって、日経225等の場合は2021/6/13なら2001/6/13以前は取得できません。


```Python:
import pyautogui
import sys
import time
import datetime

def mouce_move(x, y):
    """
    マルチモニタの場合の処置関数。人によっては不要
    マウスの現在値がアイコンと別のモニタにある場合はなぜか一発で動いてくれないので
    2回moveToで動かしている　※細かい理屈はまだわかってない
    """
    # 現在のマウスカーソル位置がメイン画面の範囲に収まっているか否かを条件分岐
    if pyautogui.position()[0] < 0 or pyautogui.size()[0] < pyautogui.position()[0]:
        #アイコンショートカットまで2回に分けて移動
        pyautogui.moveTo(x,y)
        pyautogui.moveTo(x,y)
    else: #アイコンと同じ画面にカーソルがいる場合
        pyautogui.moveTo(x,y)

#各命令のインターバル設定(おまじない程度に入れている)
pyautogui.PAUSE=1 

#ユーザーアカウント制御を無くしたSBIアイコンへマウス移動＋クリック
x1,y1 = 49,134
mouce_move(x1, y1) #最初だけ先程の関数でまずはマウス移動を行う
pyautogui.doubleClick(x1, y1) #ダブルクリックで起動

#ログイン画面表示までのWait
time.sleep(1)

#ログインボタンを押す
x2,y2 = 1062,552
pyautogui.click(x2, y2, clicks=1, button='left')

#Main画面出るまでのWait
time.sleep(5)

#main画面からチャートボタンを押す
x3,y3 = 1595,80
pyautogui.click(x3, y3, clicks=1, button='left')

#個別チャート画面表示までwait
time.sleep(1)

#ラジオボタンを指標へ切り替える
x4,y4 = 493,121
pyautogui.click(x4, y4, clicks=1, button='left')

"""
★以下は本記事の「4.起動中のイメージ」を見るとどういう動きなのかわかります
"""

#プルダウンからマザーズを選択してエンター
x5,y5 = 507,179
pyautogui.click(x5, y5, clicks=1, button='left')
pyautogui.press("down", presses=11) #マザーズは11個下を押すと出てくる
pyautogui.press("enter")

#時系列ボタンを押す
x6,y6 = 841,127
pyautogui.click(x6, y6, clicks=1, button='left')

"""取得開始日を2020年の2月1日に設定"""
#カレンダーの開始箇所をクリック
x7,y7 = 704,299
pyautogui.click(x7, y7, clicks=1, button='left')

#年を2000年に設定 ※3回クリック
x8,y8 = 725,332
pyautogui.click(x8, y8, clicks=3, button='left')

#2000年の2月に設定 ※3回クリック
x9,y9 = 703,355
pyautogui.click(x9, y9, clicks=3, button='left')

#2月1日に設定
x10,y10 = 703,362
pyautogui.click(x10, y10, clicks=1, button='left')

#検索をクリック
x11,y11 = 1016,301
pyautogui.click(x11, y11, clicks=1, button='left')

#検索結果が出るまでwait 
time.sleep(3)

#csv出力をクリック
x12,y12 = 1090,305
pyautogui.click(x12, y12, clicks=1, button='left')

"""名前を付けて保存ダイアログ操作"""

#ダイアログ表示までwait
time.sleep(1)

#ファイル名のcsvより後ろにクリックカーソルを移動
x13, y13 = 1026,725
pyautogui.click(x13, y13, clicks=1, button='left')

#名前を付けて保存画面でキーボードの左ボタンを4回押す
pyautogui.press("left", presses=4)

#そこにマザーズと本日の日付をキー入力させる
pyautogui.typewrite('_mothers_'+str(datetime.date.today()))

#ダイアログ内の保存ボタンを押す
x14, y14 = 1210,720
pyautogui.click(x14, y14, clicks=1, button='left')

#エクスポートが完了しましたダイアログを消す
x15, y15 = 1041,596
pyautogui.click(x15, y15, clicks=1, button='left')

"""ソフトを終了させる"""
#右上のバツボタンを押す
x16, y16 = 1912,3
pyautogui.click(x16, y16, clicks=1, button='left')

#ダイアログ表示までwait
time.sleep(1)

#終了しますか？　→　はい
x17, y17 = 899,578
pyautogui.click(x17, y17, clicks=1, button='left')
```

これが終わると、デスクトップにcsvが置かれている。
中身を見てみると、以下のように本日の最新までのデータが取得されていることがわかる。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/7a7b964b-5bb3-b5e8-9ae5-e14ec0d8d2e7.png" width=60%>


#4.起動中のイメージ
個人情報等あるので最初の個所はカット。フォルダ名は別にどうでもよかったが、GIF作成の勉強兼ねて一応一部モザイク処理してます。
以下クリックすると拡大して見れるので、必要であればそれで見てください

![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373060/cc545e71-ba06-f5c2-28bf-14dd86b1d7f8.gif)


#5.さいごに
世間でもRPA等が流行っていたので、個人でしかもpythonでできるPyAutoGUIを使用してHyperSBIの操作をやってみました。これで定常作業はかなり楽に処理できるのではないでしょうか？
株価ですら、スクレイピングでなくてもこれで収集もできますし、応用範囲は無限だと思ってます。
バシバシ自動化していきましょう！