Created
December 24, 2017 02:09
-
-
Save kennygt51/367c21282c5dda76f405057c8e08e4ef to your computer and use it in GitHub Desktop.
Alexaで馬券自動投票するスクリプト(Seleniumを使って馬券を購入する処理)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import re | |
import datetime | |
import lxml.html | |
import tweepy | |
from time import sleep | |
from selenium import webdriver | |
from selenium.webdriver.support.ui import WebDriverWait | |
# 対象のツイートを定期チェックするデーモン化メソッド | |
def update_check_daemon(): | |
# tweet environment | |
user_id = os.environ['TWITTER_USER_ID'] | |
consumer_key = os.environ['TW_CONSUMER_KEY'] | |
consumer_secret = os.environ['TW_CONSUMER_SECRET'] | |
access_token = os.environ['TW_ACCESS_TOKEN'] | |
access_token_secret = os.environ['TW_ACCESS_TOKEN_SECRET'] | |
# tweepy config | |
auth = tweepy.OAuthHandler(consumer_key, consumer_secret) | |
auth.set_access_token(access_token, access_token_secret) | |
api = tweepy.API(auth) | |
# 最後のツイートを取得し保持(更新があったら購入処理起動) | |
last_tweet = api.user_timeline(id=user_id)[0].text | |
print(last_tweet + "(Last Tweet)") | |
print("#-----Loop Start-----#") | |
# 更新があるまで無限ループ | |
count = 0 | |
while True: | |
check_tweet = api.user_timeline(id=user_id)[0].text | |
count+=1 | |
print(check_tweet + "(Check Tweet" + ":" + str(count) + ")") | |
if last_tweet != check_tweet: | |
print("Tweet Updated:" + "from" + last_tweet + " to " + check_tweet) | |
break | |
print("Tweet Not Updated") | |
sleep(8) | |
print("#-----Loop Stop-----#") | |
print("Buy HorseRacingTicket Start!") | |
# 購入処理開始 | |
info_buy = buy_jra_pat(check_tweet) | |
print("Fin:" + info_buy) | |
def buy_jra_pat(check_tweet): | |
# 取得したTweet内容を解析 | |
ary_hrt = check_tweet.split(":") | |
mmdd = datetime.date.today().strftime("%m%d") # システムの当日日付のレースを購入する | |
target_race_course_code = conversion_racecourse(ary_hrt[1][0:2]) # 競馬場名から競馬場コードへの変換 | |
target_race_no_fill = re.search('[0-9]*' , ary_hrt[2]).group().zfill(2) # 対象レース番号(2桁に変換) | |
horse_number = re.search('[0-9]*' , ary_hrt[3]).group() # 購入対象の馬番 | |
info_buy = '購入対象:{0}:{1}競馬場 {2}レース {3}番'.format(mmdd,ary_hrt[1],target_race_no_fill,horse_number) | |
print(info_buy) | |
# 環境変数よりPAT購入の為に必要な情報を取得 | |
INETID = os.environ['INETID'] | |
KANYUSYA_NO = os.environ['KANYUSYA_NO'] | |
PASSWORD_PAT = os.environ['PASSWORD_PAT'] | |
PRAS_NO = os.environ['PRAS_NO'] | |
NETKEIBA_ID = os.environ['NETKEIBA_ID'] | |
NETKEIBA_PASSWORD = os.environ['NETKEIBA_PASSWORD'] | |
# netkeiba.comの購入対象レースのURLを取得 | |
race_url = "" | |
open_info = get_open_info(mmdd) | |
for race_place in open_info: | |
if race_place["race_course"] == target_race_course_code: | |
race_url = format_race_url(race_place["race_course"],race_place["race_times"],race_place["race_day"],target_race_no_fill) | |
# SeleniumよりChromeを起動。馬券購入処理開始。 | |
driver = webdriver.Chrome() | |
driver.get(race_url) | |
# PAT購入画面に遷移・ログイン | |
driver.find_element_by_xpath('//*[@id="main"]/div/div/div[4]/div/ul/li/a/img').click() | |
WebDriverWait(driver, 3).until(lambda d: len(d.window_handles) > 1) | |
driver.switch_to.window(driver.window_handles[1]) | |
driver.find_element_by_name('login_id').send_keys(NETKEIBA_ID) | |
driver.find_element_by_name('pswd').send_keys(NETKEIBA_PASSWORD) | |
driver.find_element_by_xpath('//*[@id="contents"]/div[2]/div[1]/div[2]/form/input[5]').click() | |
# 券種「単勝」にチェック | |
driver.find_element_by_xpath('//*[@id="ipat_shikibetsu"]/td/ul[1]/li[1]').click() | |
# 購入する馬番にチェック | |
HN_XPATH='//*[@id="horse' + horse_number + '"]/td[7]/input' | |
driver.find_element_by_xpath(HN_XPATH).click() | |
# 100円のみ購入の為、金額入力テキストボックスに1を入力 | |
driver.find_element_by_xpath('//*[@id="ipat_selecter"]/div[3]/div[3]/div/div/input').send_keys("1") | |
# セット | |
driver.find_element_by_xpath('//*[@id="ipat_selecter"]/div[3]/div[3]/div/ul/li[12]/input').click() | |
# 入力完了謳歌 | |
driver.find_element_by_xpath('//*[@id="ipat_better"]/div[2]/div[2]/div/input').click() | |
# iNetID入力 | |
driver.find_element_by_name('inetID').send_keys(INETID) | |
# 加入者番号入力 | |
driver.find_element_by_name('userNumber').send_keys(KANYUSYA_NO) | |
# 暗証番号入力 | |
driver.find_element_by_name('pass').send_keys(PASSWORD_PAT) | |
# P-RAS番号入力 | |
driver.find_element_by_name('parsNumber').send_keys(PRAS_NO) | |
# 購入ボタン押下 | |
driver.find_element_by_name('nowCardBuy2').click() | |
sleep(3) | |
# 確認処理のため、購入金額を入力 | |
driver.find_element_by_name('totalMoney').send_keys("100") | |
# 購入! | |
driver.find_element_by_name('nowCardBuy2').click() | |
# 終了 | |
driver.quit() | |
return info_buy | |
# 引数に指定したmmdd形式の日付で開催されるレースの開催情報を取得しリストで返す | |
def get_open_info(mmdd): | |
race_list_url_template = "http://race.netkeiba.com/?pid=race_list&id=c" | |
race_list_url = race_list_url_template + mmdd | |
open_info_list = [] | |
# スクレイピング処理 | |
driver = webdriver.PhantomJS() | |
driver.get(race_list_url) | |
root = lxml.html.fromstring(driver.page_source) | |
for open_info in root.cssselect('.kaisaidata'): | |
open_info_dict = {} | |
m = re.match(r"(\d+)回(..)(\d+)日目", open_info.text) | |
open_info_dict["race_times"] = m.group(1).zfill(2) # 開催回を2桁に整形 | |
open_info_dict["race_course"] = conversion_racecourse(m.group(2)) # 開催競馬場をコード変換 | |
open_info_dict["race_day"] = m.group(3).zfill(2) # 開催日を2桁に整形 | |
open_info_list.append(open_info_dict) | |
''' | |
スクレイピング結果フォーマット | |
[ | |
{'race_course': '04', 'race_day': '10', 'race_times': '02'}, | |
{'race_course': '10', 'race_day': '10', 'race_times': '02'}, | |
{'race_course': '01', 'race_day': '04', 'race_times': '02'} | |
] | |
''' | |
return open_info_list | |
def format_race_url(race_course,race_times,race_day,race_no): | |
race_url_template = "http://race.netkeiba.com/?pid=race_old&id=c" | |
year = datetime.date.today().year | |
race_url = race_url_template + str(year) + str(race_course) + str(race_times) + str(race_day) + str(race_no) | |
return race_url | |
# 競馬場から2桁の競馬場コードへの変換関数 | |
def conversion_racecourse(rc_name): | |
rc_code = "" | |
if rc_name == "札幌": | |
rc_code = "01" | |
elif rc_name == "函館": | |
rc_code = "02" | |
elif rc_name == "福島": | |
rc_code = "03" | |
elif rc_name == "新潟": | |
rc_code = "04" | |
elif rc_name == "東京": | |
rc_code = "05" | |
elif rc_name == "中山": | |
rc_code = "06" | |
elif rc_name == "中京": | |
rc_code = "07" | |
elif rc_name == "京都": | |
rc_code = "08" | |
elif rc_name == "阪神": | |
rc_code = "09" | |
elif rc_name == "小倉": | |
rc_code = "10" | |
else: | |
rc_code = rc_name | |
return rc_code | |
# Main | |
if __name__ == "__main__": | |
update_check_daemon() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment