でんき家計簿 (くらしTEPCO) をスクレイピングしてみた (30分毎電力データ)
Abstract
PythonからくらしTEPCO経由ででんき家計簿にログインして、 自宅の30分電力使用量データを遡れるだけ取得してみた。
Introduction
前回からの続きです。
くらしTEPCOのアカウントを使ってでんき家計簿にログインし、30分電力値データを遡れるだけ取得してみた。
Setup and Results
前準備
- 前回と同じ
どこにアクセスすればデータが取れるのか?
前回の時点で、月毎電力データのページまではたどり着けた。ここから更に進めてみる。
時間別ページに飛ぶためのリンクリンクはこんな感じ。
<a href="javascript:void(0);" onclick=" createHiddenTag(fnjdoc.forms['syo_electricUsageAmountActionForm'], new Array('xxxxxxxx','yyyyyyyyyyyyy'), new Array('key.officeCd', 'key.visitNum'), true); return submitForm(fnjdoc.forms['syo_electricUsageAmountActionForm'], '/dk/syo/electricUsageAmount/goElectricUsage30minGraph', null);">
月別使用量ページの表示とほぼ同じだが、 追加でofficeVisitCd = xxxxxxxx/yyyyyyyyyyyyy と、ヘッダのRefererとして遷移元のurlを指定しないといけないみたい。
htmlからの数値読み出しは、でんき家計簿側のコードが変更されないことを祈って、形式固定の力技で抜き出してみた。 (本当はjsのパーサと書けばよいのだろうけど...)
データが抜き出せたら、前日データの表示用のリンクから同様のことを繰り返す。
コード
# 30分値表示ページから、数値データを抜き出す def getData(html_text): 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(html_text).split("\n"): if(l.startswith("function")): function = l.split("function")[1].split("()")[0].strip() if(function.startswith("vbar_usage_grp")): d[function] = {} if(function.startswith("vbar")): if(l.startswith("var items = ")): d[function]["items"] = json.loads(l.split("=")[-1].strip(";")) html = BeautifulSoup(html_text, "html.parser") date_str = html.find(id="motion_area1").find_all("td")[1].contents[0] date = datetime.datetime.strptime(date_str.split("\u3000")[0], '%a %b %d %H:%M:%S JST %Y') return (date, d["vbar_usage_grp"]["items"][0][1:-1]) # 前日移動に必要な情報 def getParamsToMovePrev(html_text): html = BeautifulSoup(html_text, "html.parser") link_js = html.find(id="motion_area1").find("a")["onclick"] #print(link_js) key_d = link_js.split("'")[3] key_date = link_js.split("'")[5] post_to = link_js.split("'")[13] return(key_d, key_date, post_to) # 前日の30分データ表示ページ を取得 def getPrev(key_d, key_date, post_to): param = { 'key.d': key_d, 'key.date': key_date } header = { 'Referer':data_page.url } data_page_30min = session.post( 'https://www.kakeibo.tepco.co.jp'+post_to, data=param, headers=header) data_page_30min.encoding = data_page_30min.apparent_encoding return data_page_30min.text #取得可能な30分値データを、全て取得 current_page = data_page_30min.text with open("./usage30min.csv", "w") as f: while True: d, date, post_to = getParamsToMovePrev(current_page) current_page = getPrev(d, date, post_to) data = getData(current_page) if(len(data[1]) != 48): break f.write(data[0].strftime('%Y-%m-%d')) for usage in data[1]: f.write(" ," + str(usage)) f.write("\n") f.flush()
実行結果
くらし家計簿から、30分毎電力値を取得し、csvファイルに書き出した。