the invention of t88

工作、資格取得、データ分析のことなど

LOTOの当選結果を自動通知する

f:id:take213uv:20190922003411j:plain

少し前からLOTOを購入をしています。

宝クジというとよく「期待値が〜」という声が上がりますが、分散を考えるとそうバカにしたものでもないですよね。300円が数億に化けるなんて事は普通無い。まさに夢を買っていると言えます。

そんなわけで毎回1口ずつ、チマチマと購入して日々のちょっとした刺激として楽しんでいます。

今はLOTO6とLOTO7を買ってます。LOTO6は月木、LOTO7は金、計3回/週、購入しています。購入自体は口座を持っている銀行で定期購入できています。一方で、購入したものが当たったのか、その確認は手動でしないといけません。

この当選確認を自動化したいよね、というのが今回の取り組みです。

pythonで処理作成

WEBから当選結果を読み取る

今回はこちらのサイトを使用させていただきました。 lotonumbers.info

f:id:take213uv:20190922013845p:plain

beautiful soupを使ってスクレイピングします。

import urllib.request
from bs4 import BeautifulSoup

url = 'http://lotonumbers.info/loto6/number/'
request = urllib.request.Request(url=url)
response = urllib.request.urlopen(request)
html = response.read()
soup = BeautifulSoup(html)

soupの中身はこんな感じになっています。

f:id:take213uv:20190922012720p:plain

thに第何回かの情報が入っています。
tdに当選番号の情報が入っています。
新しい順に並んでいるので、bsのfindで一つ目を抽出してやれば自動的に最新の結果のみ抽出できそうです。

no = soup.find('th').string
win_num = soup.find('td').string


win_numは若干ごみが混じっています。

f:id:take213uv:20190922012938p:plain

ごみを取りつつ、リストにしておきます。

win_num = win_num.replace('\xa0(',',')
win_num = win_num.replace(')','')
win_num = win_num.split(',')

f:id:take213uv:20190922013322p:plain

本数字とボーナス数字を分けておきます。

win_num_main = win_num[0:6]
win_num_bonus = win_num[6]

当選結果を判定する

LOTO6の当選結果は下記の通りです。
f:id:take213uv:20190922014201p:plain
単純に本数字とボーナス数字にどれだけマッチしたか、で判別されます。
一致数をカウントし、その数で条件分岐させ、結果を判定します。

my_num = ['01','02','03','04','05','06']

match_main = len(set(my_num) & set(win_num_main))
match_bonus = len(set(my_num) & set(win_num_bonus))

if match_main < 3 : result = 'ハズレ'
elif match_main == 3 : result = '5等'
elif match_main == 4 : result = '4等'
elif match_main == 6 : result = '1等'
elif match_main == 5 :
    if match_bonus == 1:
        result = '2等'
    else :
        result = '3等'

結果をLINEで通知

LINE Notifyを使って通知します。

import requests

# LINEで通知
message = \
'LOTO6 ' + no + '\n\n' + \
'[購入番号]\n' + \
' '.join(my_num) + '\n\n' + \
'[当選番号]\n' + \
'本数字:\n' + \
' '.join(win_num_main) + '\n'  \
'ボーナス数字:\n' + \
win_num_bonus + '\n\n' + \
'本数字の一致数:'  + str(match_main) + '\n' + \
'ボーナス数字の一致数:'  + str(match_bonus) + '\n' + \
'結果: ' + result

url = "https://notify-api.line.me/api/notify"
access_token = '**token**'
headers = {'Authorization': 'Bearer ' + access_token}

payload = {'message': message}
r = requests.post(url, headers=headers, params=payload)

参考:

qiita.com

output

f:id:take213uv:20190922015646j:plain

コード全体

# パッケージのインストール
import urllib.request
from bs4 import BeautifulSoup
import requests


# 自分が購入している番号
my_num = ['01','02','03','04','05','06']


# 当選番号をwebサイトからスクレイピング
url = 'http://lotonumbers.info/loto6/number/'
request = urllib.request.Request(url=url)
response = urllib.request.urlopen(request)
html = response.read()
soup = BeautifulSoup(html)

no = soup.find('th').string
win_num = soup.find('td').string


# 文字列の整形
win_num = win_num.replace('\xa0(',',')
win_num = win_num.replace(')','')
win_num = win_num.split(',')

# 本数字とボーナス数字に分ける
win_num_main = win_num[0:6]
win_num_bonus = win_num[6]

# 一致数を確認
match_main = len(set(my_num) & set(win_num_main))
match_bonus = len(set(my_num) & set([win_num_bonus]))

# 当選結果を判定
if match_main < 3 : result = 'ハズレ'
elif match_main == 3 : result = '5等'
elif match_main == 4 : result = '4等'
elif match_main == 6 : result = '1等'
elif match_main == 5 :
    if match_bonus == 1:
        result = '2等'
    else :
        result = '3等'
        
# LINEで通知
message = \
'LOTO6 ' + no + '\n\n' + \
'[購入番号]\n' + \
' '.join(my_num) + '\n\n' + \
'[当選番号]\n' + \
'本数字:\n' + \
' '.join(win_num_main) + '\n'  \
'ボーナス数字:\n' + \
win_num_bonus + '\n\n' + \
'本数字の一致数:'  + str(match_main) + '\n' + \
'ボーナス数字の一致数:'  + str(match_bonus) + '\n' + \
'結果: ' + result

url = "https://notify-api.line.me/api/notify"
access_token = '**token**'
headers = {'Authorization': 'Bearer ' + access_token}

payload = {'message': message}
r = requests.post(url, headers=headers, params=payload)

AWS lambdaで定期実行させる

先ほどのpythonスクリプトを実行すれば、最新の当選番号と自分の番号を比較して、結果をLINEに通知できます。あとは当選番号の更新が行われるタイミングで定期的に実行すればokです。

ただし、このためだけにPCをスタンバイさせておくのも非常に勿体ないので、AWS lambdaを使ってサーバレスに処理を回したいと思います。

lambdaで処理を実行するに当たっては、使っているパッケージも合わせてupしておく必要があります。下記の記事を参考に、一つのzipファイルに固めてアップロードしました。

参考:

tech.bita.jp

作成したlambdaファンクションをCloudWatch Eventsをトリガーにして、定期実行させます。

f:id:take213uv:20190922021243p:plain

実行タイミングはcronで指定可能です。
毎週月木が開票日、データ取得元の更新は遅くとも22時には完了しているだろう、という想定のもと、下記のような条件にしています。
cron(0 13 ? * MON,THU *)
※UTC基準なので-9hした値となっています。

これで完成。

まとめ

LOTO7についてもLOTO6のマイナチェンジで作成しました。
これで完全自動で購入→当選確認ができるようになりました。
あとは果報を寝て待つだけ。

PythonによるWebスクレイピング 第2版

PythonによるWebスクレイピング 第2版

  • 作者: Ryan Mitchell,嶋田健志,黒川利明
  • 出版社/メーカー: オライリージャパン
  • 発売日: 2019/03/26
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る