自作AIスピーカーに、桂川駅から10分後以降に出る次の電車とその次の電車の時間を教えてくれる機能を実装。
pythonのpandasを使うと、3行ぐらいで時刻表のhtmlからテーブルが取れてしまうのには驚いた。
url=“時刻表のurl”
df = pandas.io.html.read_html(url)
data=(df[1].fillna(' ')).values[:,:]
でもこの後が面倒臭い。セルの中に行き先と時刻が混在している。これからの社会に必要なのは人間にもプログラムにもわかりやすいページを作ることなのか。それとも人間が見てわかるぐらいだから、画像データとして畳み込みニューラルネットに突っ込んでデータを抽出すれば良いのか。
いざデータを取ろうと思って調べてみるとxmlでデータを提供してくれているところは意外に少ないので、実は後者の方が有効なのかもしれない。htmlを解析しても、要素同士の表示位置の関係は分かりにい。人間はブラウザで2次元画像になったあとのものを見ているので、理解できるのかも。
# -*- coding: utf-8 -*- import numpy as np import pandas import re import datetime import subprocess import os pattern=r'([0-9]+$)' pattern2=r'(^[^0-9 ]+)' url="http://time.jr-odekake.net/cgi-bin/mydia.cgi?MODE=11&FUNC=0&EKI=桂川&SENK=JR京都線&DIR=京都・草津方面&DDIV=&CDAY=&DITD=8251011001100,8251011001400,8251011001110,8251011001410&COMPANY_CODE=4&DATE=20180306" today=datetime.datetime.today() filename='/home/pi/tmp/'+today.strftime('%Y%m%d')+'_ktg_kyo.csv' if os.path.exists(filename) == False: df = pandas.io.html.read_html(url) df[1].to_csv(filename,encoding='utf_8') df=df[1] data=(df.fillna(' ')).values[:,:] else: df=pandas.read_csv(filename,encoding='utf_8') data=(df.fillna(' ')).values[:,1:] time_list=[] bound_list=[] for i in range(4,25): for j in range(1,data.shape[1]): tmp=data[i,j].encode('utf_8') if tmp!=' ': if i+1<24: time_list.append(datetime.datetime(today.year,today.month,today.day,i+1,int(re.findall(pattern,tmp)[0]),0)) else: time_list.append(datetime.datetime(today.year,today.month,today.day+1,i+1-24,int(re.findall(pattern,tmp)[0]),0)) bound_list.append(re.findall(pattern2,tmp)[0].replace('快G','快速').replace('快H','快速')+'行き') for index in range(len(time_list)): if time_list[index]>today+datetime.timedelta(minutes=10): sentence='つぎの、かつらがわ駅の電車は、'+str(time_list[index].hour)+'時'+str(time_list[index].minute)+'分の'+bound_list[index]+'です。' print(sentence) subprocess.call(['bash','/home/pi/scripts/jsay.sh',sentence]) if index+1 <len(time_list): sentence='そのつぎの電車は、'+str(time_list[index+1].hour)+'時'+str(time_list[index+1].minute)+'分の'+bound_list[index+1]+'です。' print(sentence) subprocess.call(['bash','/home/pi/scripts/jsay.sh',sentence]) break filename='/home/pi/tmp/'+(today-datetime.timedelta(days=1)).strftime('%Y%m%d')+'_ktg_kyo.csv' if os.path.exists(filename) == True: os.remove(filename)