ひゃまだのblog

ひゃまだ(id:hymd3a)の趣味のブログ

BashでGoogleファイナンスをスクレイピング

(2023-04-06 初稿 - 2023-04-27 追記)

はじめに

来年(2024年)から新NISAが始まるようで、投資するお金はないけど、投資の練習だけはしておこうと、Googleファイナンススクレイピングするbashスクリプトを作った。(笑)

スクレイピングは、python等の高級言語で作るのが一般的みたいだが、bashで作ったのは趣味の問題。^^;

ここでは、単純にするために、S&P500とドル円の為替レートを取得する方法を記述する。他の投資先でもURLを変更すれば、対応可能だと思う。

また、他のWebサイトのスクレイピングの参考になるように、まずは筆者が行った解析方法を紹介する。

解析方法

  1. GoogleファイナンスでS&P500のURLを取得
  2. Curl -Oで取得したURLのコンテンツをファイルに保存
  3. 調べたときのS&P500の株価は、4,100.60ドルだったので、この金額を検索してhtmlタグを調べる
  4. <div class="YMlKec fxKbKc">4,100.60</div>を発見
  5. 上記タグの数値をpupまたはsedで取り出す

pupを使って楽に取得

go言語で作成されたpupを使うと、タグ内の数値を簡単に取り出すことができる。

ちなみに、Debianにおけるpupのインストールは以下のとおり。

sudo apt install pup

タグ内の抽出は、以下のサイトを参考にさせていただいた。多謝。

まずは、curlでS&P500のコンテンツをダウンロードして標準出力し、pupでタグ内の数値を取り出す。

$ curl -s "https://www.google.com/finance/quote/.INX:INDEXSP?sa=X&ved=2ahUKEwjEgLDi3ZH-AhV6pVYBHRLCA68Q3ecFegQIKhAg" | pup '[class="YMlKec fxKbKc"] text{}'
4,100.60

筆者は、URLをダブルクォートしてなくて、小一時間以上「わが家のcurlは、なんで標準出力してくれないのだろう…」と悩んだ。^^;

それにしても、とっても簡単に取り出せてpupすばらしい。

(2023-04-26追記)

上記で取得できるのだが、場合によって時間外の取引があるようで、検索のキーワードを"data-last-price"に変更した。

$ curl -s "https://www.google.com/finance/quote/.INX:INDEXSP?sa=X&ved=2ahUKEwjEgLDi3ZH-AhV6pVYBHRLCA68Q3ecFegQIKhAg" | pup 'json{}' | grep "data-last-price"
                     "data-last-price":  "4071.63",

ここまで、出力できれば、ダブルクォートを区切り文字にして、cutするだけ。

$ curl -s "https://www.google.com/finance/quote/.INX:INDEXSP?sa=X&ved=2ahUKEwjEgLDi3ZH-AhV6pVYBHRLCA68Q3ecFegQIKhAg" | pup 'json{}' | grep "data-last-price" | cut -d '"' -f 4
4071.63

いずれにしても、pupでjsonに変更してgrepすると目的数字の切り出しが簡単になるからすばらしい。

(追記終了)

sedを使って頑張って取得

pupをインストールできない等といった環境があるかわからないが、pupの存在を知らなかったので、grepsedを使って、タグ内の数値を取り出した。まあ、sedのお勉強ができたので良しとする。(^^ゞ

curl -s "https://www.google.com/finance/quote/.INX:INDEXSP?sa=X&ved=2ahUKEwjEgLDi3ZH-AhV6pVYBHRLCA68Q3ecFegQIKhAg" | grep "YMlKec fxKbKc" | sed -e 's/.*<div class="YMlKec fxKbKc">\([0-9,\.]\{8\}\)<\/div>.*$/\1/'
4,100.60

sedで数値の抽出は手抜きで、数字とカンマとピリオドが連続して8個つながった文字列を抽出しているだけなので、しっかりと抽出したい場合は、適宜変更してね。

(2023-04-22 追記)

いろいろな株価を調べてみたら、文字化けが起こる場合があったので、pupに--charset オプションを追加した。

お手元の環境に合わせて、文字コードを変更してね。

(追記終了)

(2023-04-24 追記)

sedでいろいろな株価を調べたら、数値が抽出できないことがあったので、Webサイトから通貨記号をコピペして修正。

特に円マークは、2種類あるようなので、注意。

(追記終了)

(2023-04-26追記)

いろいろな株価を見ていたら、円マークは2種類だけでなく他種類あることがわかり、面倒になったので、単位はカットし、自分でつけることにした。

(追記終了)

(2023-04-27追記)

結局、sedでも data-last-price="xxxxx"を取得することにした。

(追記終了)

作成したスクリプト

#!/usr/bin/bash
# google finace scraping
# ver0.01 2023-04-05 start
# ver0.07 2023-04-26 pup 取得方法 data-last-price 変更

# global
declare -A URL_dict     # 連想配列

URL_dict[0:DOLLEN(¥/$)]="https://www.google.com/finance/quote/USD-JPY?sa=X&ved=2ahUKEwjTw__l25H-AhUdsVYBHQ-yCpgQmY0JegQIBhAd"
# 131.7390

URL_dict[1:SP500($)]="https://www.google.com/finance/quote/.INX:INDEXSP?sa=X&ved=2ahUKEwipwurvhpT-AhUTFogKHX8MBjQQ3ecFegQILBAg"
# 4,100.60

URL_dict[2:RAKUTEN(¥)]="https://www.google.com/finance/quote/5838:TYO?sa=X&ved=2ahUKEwip7K3x_bv-AhUQCYgKHfXQDVUQ3ecFegQIHhAg"
# ¥1930.00

kword='YMlKec fxKbKc'           # 検索キーワード
#Value='\([\$¥¥¥0-9,\.]\+\)'    # sedで抽出する文字列(手抜き)¥はコピー
Value='\([0-9,\.]\+\)'          # sedで抽出する文字列(数字のみ)
PUP=0                           # 1:pup利用 0:sed利用

# function
prn_dat() {
    echo -n $1": "
    if  $PUP -eq 1 ; then
        #curl -s ${URL_dict[$1]} | pup --charset UTF-8 '[class="YMlKec fxKbKc"] text{}'
        curl -s ${URL_dict[$1]} | pup 'json{}' | grep "data-last-price" | cut -d '"' -f 4
    else
        curl -s ${URL_dict[$1]} | grep "$kword" | sed -e "$sword"
    fi
}

#sword='s/.*<"YMlKec fxKbKc">[^0-9]*'$Value'<\/div>.*$/\1/'
sword='s/^.*data-last-price="'$Value'" .*$/\1/'

#echo ${!URL_dict[@]} 
#echo ${URL_dict[@]} 
for key in ${!URL_dict[@]} 
do
    prn_dat $key 
done | sort

おわりに

上記のスクリプトを作ったのは、アメリカとの時差の問題で、取引時間の大半は寝ている時間なので、以下のようなお知らせを考えた。

if 株安 and 円高 ⇒ 「旦那はん、買いでっせ」

elif 株高 and 円安 ⇒ 「旦那はん、売りでっせ」

ちなみに、株の高い安い、為替の円高、円安の閾値は、皆さんが決めてね。

上記のスクリプトを作ったら、crontabに登録してラズパイに30分間隔で調べてもらい、寝ているときでもnotifyかLine Botでお知らせしてもらおうかと思っている。ウシシ

notifyやLine Botが気になる方は、以下をどうぞ。

関連ページ