S0-ma's Blog

s0-maのブログです。

でんき家計簿 (くらしTEPCO) をスクレイピングしてみた (月毎電力データ)

Abstract

PythonからくらしTEPCO経由ででんき家計簿にログインして、 自宅の月毎電力使用量データを取得してみた。

Introduction

自宅の電力計がスマートメーター化され、東京電力くらしTEPCOというサイトから自宅の30分電力使用量が取得できるらしい。 ただ私の場合、契約が電力自由化前のものであるため、調べてみるとでんき家計簿という別のサイトを使わないと電力値の取得ができないことが判明。

幸いくらしTEPCO経由ででんき家計簿にログインする方法が用意されていた。 くらしTEPCOのアカウントを使ってでんき家計簿ログインし、手始めに月毎電力値データ表示ページを取得してみた。

Setup and Results

前準備

  • 前回と同じ

どこにアクセスすればデータが取れるのか?

くらしTEPCOのログイン後マイページにはでんき家計簿へのリンクがある。

f:id:s0-ma:20190211150914j:plain
くらしTEPCO でんき家計簿リンク

この部分のHTMLはこんな感じ。

f:id:s0-ma:20190211151350j:plain

くらしTEPCOにログインした状態で https://www.kakeibo.tepco.co.jp/pf/ja/pco/mypage/redirect-sso.page?sitekbn=kakeibo に行くと、でんき家計簿の会員ホームに飛ばされるということみたい。

未ログイン状態だと普通にログインフォームが表示されるので、どうやらでんき家計簿くらしTEPCOと同じ要領でやれば良さそう。

でんき家計簿ログイン後に、電力使用値を表示するページに移動するための「使用量と料金をグラフで見る」リンクはこんな感じ。

<a href="javascript:void(0);" onclick="
    createHiddenTag(fnjdoc.forms['com_menuActionForm'], new Array('xxxxxxxx','yyyyyyyyyyyyy','amount'), new Array('key.officeCd', 'key.visitNum', 'key.display'), true);
    return submitForm(fnjdoc.forms['com_menuActionForm'], '/dk/com/menu/goElectricUsageAmount', null);
">

key.officeCd = xxxxxxxxxとkey.visitNum=yyyyyyyyyyyyyを/dk/com/menu/goElectricUsageAmountにpostすればよいみたい。 これで月別使用量のページが得られる。

データ自体はhtml内部の// <![CDATA[と書かれた領域に埋め込まれていた。 この領域をひとまず切り出して、後は力技で該当部分を切り出してみる。

コード

# くらしtepcoからでんき家計簿にログイン
param = {
        'ACCOUNTUID': username,
        'PASSWORD': password,
        'HIDEURL': '/ls/pf/ja/pco/mypage/redirect-sso.page?sitekbn=kakeibo',
        'LOGIN': 'EUAS_LOGIN',
        }

header = {
        'Referer': 'https://www.kakeibo.tepco.co.jp/dk/com/menu/'
        }

login = session.post(
        'https://www.kurashi.tepco.co.jp/kpf-login', data=param, headers=header)
login.encoding = login.apparent_encoding

# 月ごとデータへの移動リンクで発火するjs関数から、必要な情報を抜き出す
html = BeautifulSoup(login.text, "html.parser")
link_js = html.find(id="frame3").find(class_="box01 box firstBox").find("a")["onclick"]
#print(link_js)
key_officeCd = link_js.split("'")[3]
key_visitNum = link_js.split("'")[5]
key_display = link_js.split("'")[7]
post_to = link_js.split("'")[17]

# 月ごとデータの表示ページ に移動
param = {
        'key.officeCd': key_officeCd,
        'key.visitNum': key_visitNum,
        'key.display': key_display
}

header = {
        'Referer':login.url
        }

data_page = session.post(
        'https://www.kakeibo.tepco.co.jp'+post_to, data=param, headers=header)
data_page.encoding = data_page.apparent_encoding

# CDATA領域を切り出し
def getCDATA(text):
    ret = ""
    isInCDATAArea = False
    for l in text.split("\n"):
        l = l.strip()
        if (l == "// <![CDATA["):
            isInCDATAArea = True
        elif (l.strip() == "// ]]>"):
            isInCDATAArea = False
        
        if(isInCDATAArea):
            ret += l + "\n"
        
    return ret

# 月毎データを抜き出す
d = {}
function = ""
for l in getCDATA(data_page.text).split("\n"):
    
    if(l.startswith("function")):
        function = l.split("function")[1].split("()")[0].strip()
        if(function.startswith("vbar")):
            d[function] = {}
        
    if(function.startswith("vbar")):
        if(l.startswith("var items = ")):
            d[function]["items"] = l.split("=")[-1]

        if(l.startswith("x:")):
            d[function]["x"] = json.loads(l.split(":")[-1])
        
        if(l.startswith(",y:")):
            d[function]["y"] = json.loads(l.split(":")[-1])

# 表示
for f in d:
    print(f)
    for k in d[f]:
        print("\t", k, "\t", d[f][k])

実行結果

くらし家計簿から、月毎電力値の表示ページのhtmlを取得し、書かれているデータを抜き出すことができた。

Reference

github.com

www.kurashi.tepco.co.jp www.kakeibo.tepco.co.jp