見出し画像

(文系のPython)Yahoo Financeからデータを取得-7 (4年分の配当金を取得)

(目的)
Yahoo finance (https://finance.yahoo.com)からデータを取得。
4年分の配当金も取得する。アウトプットは下記。

(背景)
純利益(Net Income, NI)、営業キャッシュフロー(Cashflow From Operating Activities, CFO)、売上高(Net Sales もしくはRevenue)だけでなく、配当金もチェックしたいから。「タコ配」かどうかチェックできる。

Yahoo financeまで行ってわざわざいろんなとこから数字持ってきてエクセルにコピペするのは大変なのでコマンドプロンプトから一発でグラフを作れるようにした。

(前提条件)
・Pythonをインストールしている
・コマンドプロンプトからpyファイルを呼び出せる
・BeautifulSoupをインストールしている
・matplotlibをインストールする

(やり方)
まず、前の記事を参考にコードを書く。

(*前の記事は前々の記事を参考にしてたりして、結局3~4個遡る)

次に、キャッシュフローのURL(1行目)を読み込んで(2行目)、BeautifulSoupでタグ化した後(3行目)、tdタグをすべて取得し(4行目)、tdタグの中からDividends Paidの横にある数字を取るため自作関数withdrawDataを使い値をリストpreDividendLIstに入れる。

データ取得後、リストの数値それぞれに-1をかける。財務活動によるキャッシュフローから値を引っ張ってきているので、配当金をいくら払ったか(-$xx)が記載されている。あとでグラフにするときに配当金はいくらか(つまり+$xx)を知りたいのでそうしている。
DividendList = [x * -1 for x in preDividendList]

url = "https://finance.yahoo.com/quote/%s/cash-flow" %x

html = urlopen(url).read()
soup = BeautifulSoup(html,'html.parser')

td_tags = soup('td')

for tag in td_tags:
    try:
        if tag.span.text == "Dividends Paid":   #なぜかPaidのPを大文字にするしないとキャッチしない
            preDividendList = withdrawData(tag)
            DividendList = [x * -1 for x in preDividendList]
    except:
        pass

withdrawDataの中身

def withdrawData(tag):      #繰り返し使うので関数化
    tagx = tag
    periodlist = []
    for x in range(4):      #4回繰り返し(探しあてたtdタグの右4つを取得)
        tagx = tagx.next_sibling
        #print(tagx.span)    #エラーを見つけたときに使ったprint
        if tagx.span:
            try:
                text = int(tagx.span.text.replace(",",""))
            except:
                text = tagx.span.text
            periodlist.append(text)
        else:
            periodlist.append(0)
    periodlist.reverse()    # 左から右の時系列に並び替え
    return periodlistあ

前回からの変更点
Dividendの額が0の場合、Yahoo financeでは"-"と記載されている。しかも他のtagと違って、tdタグ直下のspanタグに値が書かれているのではなく、tdタグに"-"が入っていて、下記のtry-exceptでNoneが返ってきてしまう。エラーが出てしまう。

            try:
                text = int(tagx.span.text.replace(",",""))
            except:
                text = tagx.span.text

なので、if-elseをかませて、tdタグ直下にspanタグがない場合は単純に0をリストに入れている。

        if tagx.span:
            try:
                text = int(tagx.span.text.replace(",",""))
            except:
                text = tagx.span.text
            periodlist.append(text)
        else:
            periodlist.append(0)

あとは、matplotlibをちょっとだけ変更した。font.sizeを小さくしたり、barのx軸を4つに変えた。
axs[c].bar([1, 2, 3, 4], y, tick_label = label)

sumlst = [DividendList, NetIncomeList, CFFrmOPList, RevenueList]
label = ["Div", "NI", "CFO", "Net Sales"]
print(label)

plt.rcParams["font.size"] = 3.5
fig, axs = plt.subplots(1, 4, figsize=(5, 2),dpi=200, sharey='all')

for c in range(4):
    latest = [x[c] for x in sumlst]
    print(PeriodList[c], latest)

    y = latest
    axs[c].bar([1, 2, 3, 4], y, tick_label = label)
    axs[c].set_title(PeriodList[c])

plt.show()

・・・おしまい。


以下コード全文

from urllib.request import urlopen
from bs4 import BeautifulSoup

import matplotlib.pyplot as plt

def withdrawData(tag):      #繰り返し使うので関数化
    tagx = tag
    periodlist = []
    for x in range(4):      #4回繰り返し(探しあてたtdタグの右4つを取得)
        tagx = tagx.next_sibling
        #print(tagx.span)    #エラーを見つけたときのprint
        if tagx.span:
            try:
                text = int(tagx.span.text.replace(",",""))
            except:
                text = tagx.span.text
            periodlist.append(text)
        else:
            periodlist.append(0)
    periodlist.reverse()    # 左から右の時系列に並び替え
    return periodlist

x = input('input Ticker symbol:')

url = "https://finance.yahoo.com/quote/%s/cash-flow" %x

html = urlopen(url).read()
soup = BeautifulSoup(html,'html.parser')

td_tags = soup('td')

for tag in td_tags:
    try:
        if tag.span.text == "Period Ending":
            PeriodList = withdrawData(tag)
    except:
        pass

    try:
        if tag.span.text == "Total Cash Flow From Operating Activities":
            CFFrmOPList = withdrawData(tag)
    except:
        pass

    try:
        if tag.span.text == "Net Income":
            NetIncomeList = withdrawData(tag)
    except:
        pass
    try:
        if tag.span.text == "Dividends Paid":   #なぜかPaidのPを大文字にするしないとキャッチしない
            preDividendList = withdrawData(tag)
            DividendList = [x * -1 for x in preDividendList]
            #もし"-"だったら0に変える
    except:
        pass

url = "https://sg.finance.yahoo.com/quote/%s/financials" %x

html = urlopen(url).read()
soup = BeautifulSoup(html,'html.parser')

td_tags = soup('td')

for tag in td_tags:
    try:
        if tag.span.text == "Total revenue":
            RevenueList = withdrawData(tag)
    except:
        pass

sumlst = [DividendList, NetIncomeList, CFFrmOPList, RevenueList]
label = ["Div", "NI", "CFO", "Net Sales"]
print(label)

plt.rcParams["font.size"] = 3.5
fig, axs = plt.subplots(1, 4, figsize=(5, 2),dpi=200, sharey='all')

for c in range(4):
    latest = [x[c] for x in sumlst]
    print(PeriodList[c], latest)

    y = latest
    axs[c].bar([1, 2, 3, 4], y, tick_label = label)
    axs[c].set_title(PeriodList[c])

plt.show()
ありがとうございます!すごくほくほくした気持ちになれました。
2
1986年生まれ / シンガポール在住中