Pythonで、メールで乗り換え検索
去年書いた、メールで「えきから時刻表」の乗り換え案内を拝借するスクリプトが出てきた。
レンタルサーバーに置いてCRONしてたけど、なんとまだ使える!
ただ、こんなスーパー決めうち地獄コードは、二度とメンテしたくない!
#!/usr/bin/env python #coding: utf-8 """ http://i.ekikara.jp/cgi-bin/route_mobile.cgiをメールで拝借するスクリプト。 cronで。 次の本文でメールすると、検索結果が返信される。 乗車駅名 降車駅名 複数の同名駅があるときは、それらの駅番号が返信されるので、 駅名を目当ての駅の番号で置き換えて、またメールする。 """ import datetime from email.parser import Parser from email.mime.text import MIMEText import imaplib import smtplib import urllib import httplib import sgmllib import re HOSTNAME = "ここには、メールのホスト名を書く" USERNAME = "ここには、乗り換え検索を受けるメールアドレスを書く" PASSWORD = "ここには、メールのパスワードを書く" FROM = USERNAME class TagStripper(sgmllib.SGMLParser): """ http://www.codereading.com/codereading/python/strip-html-tags.htmlでひろった HTMLタグを取り除くパーザー。 """ def __init__(self): sgmllib.SGMLParser.__init__(self) def strip(self, some_html): self.theString = "" self.feed(some_html) self.close() return self.theString def handle_data(self, data): self.theString += data tag_stripper = TagStripper() m = imaplib.IMAP4_SSL(HOSTNAME) m.login(USERNAME, PASSWORD) m.select() unused, mailnums = m.search(None, "UNSEEN") for num in mailnums[0].split(): unused, data = m.fetch(num, "RFC822") headers = Parser().parsestr(data[0][1]) charset = headers.get_charsets()[0] recv_body = headers.get_payload().strip() if len(recv_body.split(" ")) != 2: body = ["You searched it: %s\n" % recv_body, "Transfer search system could not find it.", "Your request has some problem.", "Please confirm the station name or number and remember how to use it."] sent_body = "\n".join(body).decode("shift-jis").encode(charset) s = smtplib.SMTP(HOSTNAME) msg = MIMEText(sent_body) msg.set_charset(charset) msg.set_type("text/plain") msg["Subject"] = "" msg["From"] = FROM TO = headers["From"] msg["To"] = TO s.sendmail(FROM, TO, msg.as_string()) s.quit() continue intext, outtext = recv_body.split(" ") incode, outcode = "", "" if intext.isalnum(): incode = intext if outtext.isalnum(): outcode = outtext intext_param = urllib.urlencode({ "intext": intext.decode(charset).encode("shift-jis")}) # 出発駅 outtext_param = urllib.urlencode({ "outtext": outtext.decode(charset).encode("shift-jis")}) # 到着駅 incode_param = urllib.urlencode({ "incode": incode.decode(charset).encode("shift-jis")}) # 出発駅コード outcode_param = urllib.urlencode({ "outcode": outcode.decode(charset).encode("shift-jis")}) # 到着駅コード now = datetime.datetime.now() year_month = "".join(["%04d"%now.year, "%02d"%now.month]) day = str(now.day) hour = str(now.hour) minute = str(now.minute) url = "".join(["/cgi-bin/route_mobile.cgi?", intext_param, "&", outtext_param, "&", incode_param, "&", outcode_param, "&now_time=%3C%3C+%8C%BB%8D%DD%8E%9E%8D%8F%82%C5%8C%9F%8D%F5+%3E%3E&month=", year_month, "&day=", day, "&way=&hour=", hour, "&min=", minute, "&arrive=&airplane=on&sprexprs=on&utrexprs=on&max=3&sort=time&half=on&cut=on&direct=on&.cgifields=utrexprs&.cgifields=way&.cgifields=sprexprs&.cgifields=airplane"]) conn = httplib.HTTPConnection("i.ekikara.jp:80") conn.request("GET", url) res = conn.getresponse() html = res.read() conn.close() l = [] l.append(" ".join(["You searched it:", intext, outtext]).decode(charset).encode("shift-jis")) keywords = ["clock", "money", "foot", "depart", "arrive"] alias = {"clock": "total time", "money": "fee", "foot": "transfer", "depart": "depart", "arrive": "arrive"} station_duplicated = False no_such_station = False result_counter = 1 for line in html.splitlines(): if "form" in line: # 複数の同名駅があるときだけ"form"含むレスポンスが返ってくる if "select" in html and "option" in html: station_duplicated = True else: no_such_station = True break for kw in keywords: if kw in line: if "*." in line: continue if kw == "clock": l.append("\n*** search result %d ***" % result_counter) result_counter += 1 l.append("".join([alias.get(kw), ": ", tag_stripper.strip(line)])) continue if station_duplicated == True: l.append("\nTransfer search system found a several stations with same name.") l.append("Please send again with station number below instead of station name.") for line in html.splitlines(): if "select" in line: l.append("") if "option" in line: code = re.match(r"""^.*"(?P<code>.*)".*$""", line).groupdict()["code"] if not code: continue l.append("".join([code, ": ", tag_stripper.strip(line)])) if no_such_station == True: l.append("\nTransfer search system could not find it.") l.append("Your request has some problem.") l.append("Please confirm the station name or number and remember how to use it.") sent_body = "\n".join(l).decode("shift-jis").encode(charset) s = smtplib.SMTP(HOSTNAME) msg = MIMEText(sent_body) msg.set_charset(charset) msg.set_type("text/plain") msg["Subject"] = "" msg["From"] = FROM TO = headers["From"] msg["To"] = TO s.sendmail(FROM, TO, msg.as_string()) s.quit() #検索済みの既読メールを残さないなら、コメントを外す #m.store(num, "+flags", "\\deleted") #m.expunge() m.logout()