【Pythonの勉強】馬券購入履歴取得プログラムの作成 その3

前回はようやくClub JRA-Netの投票照会画面までたどり着くことが出来ました。
【Pythonの勉強】馬券購入履歴取得プログラムの作成 その2

単独で馬券の購入履歴の照会ページまで行くことはできました。
今回はループを回して、2ヶ月前までの投票履歴を取得してみるところになります。

初めにお断りしておきますが、今回はかなりとりとめのない記事になっています。
また、今回の処理はすべて完成した後に見直して、良いプログラムになるように改善するつもりです。

短期的な目的はプログラムを完成させることですが、長期的にはより良いプログラムが書けるようになることが目的です。
仕事でやっているぶんには、なかなか完成したプログラムを全面的に書き直すことはできません。
しかし、このプログラムは趣味でやっているので、何回でも同じ物を作ってもいいわけですね。

さて、馬券の購入履歴ですが、初めに以下の手段でやってみました。
結果的にエラーになってしまうんですけどね…

エラーになったパターン

始めに、日付選択画面のcss selectorでtrダグまで取得して変数に代入しました。

# 日付選択画面
e = browser.find_elements_by_css_selector('body > center > table > tbody > tr')

上記のseleniumオブジェクトをループで回します。
その中でtdタグを取得します。(=「選択」ボタン)
「選択」ボタンをクリックして次の受付番号選択画面に行きます。

受付番号選択画面も同様です。
trダグを取得してseleniumオブジェクトを作成し、別の変数に代入します。
ループで回してtdタグを取得します。
「選択」ボタンをクリックしていきます。

# 受付番号選択画面
e2 = e.find_elements_by_css_selector('body > center > table:nth-child(11) > tbody > tr')

受付番号選択画面で選択ボタンをクリックすると、投票内容照会画面が表示されます。
ここでようやく、対象の投票データを取得することができるようになります。
完成版ではDBに保存するのですが、まずはお試しで取得した内容を画面に表示するだけに留めます。

投票データを取得して画面に表示させたら、次の受付番号に行きます。
受付番号選択ボタンを押していったん、受付番号選択画面に戻ります。

無事に受付番号選択画面に戻ることが出来ましたが、次の受付番号の行くために「選択」ボタンを押すとエラーになってしまいました。

まず、直感的にseleniumのオブジェクトをループさせているのがまずいのだと思いました。
ループの中で前の画面に戻るボタンを押して、次のループに移ったときにオブジェクトがおかしな状態になっているだと想定されます。

そこで、seleniumのオブジェクトをループで回すのではなく、css selectorで取得する値をlistに保持しておくことにしました。
listをループさせ、その中でseleniumのオブジェクトを生成するのです。

プログラムを変更させ、試しに動かしてみました。
すると、無事にすべての投票履歴を画面に表示することができました。

かなり力技になりましたが、まずはやりたいことを実現させるのが優先ですっ!

成功したパターン

日付選択画面でcss selectorをまとめて取得して、listに格納します。

e = browser.find_elements_by_css_selector('body > center > table > tbody > tr')
days = []
# tr:nth-child() の値 1から始まって3ずつ増加(1,4,7, ...)
for i in range(1, len(e) * 3, 3):
    days.append('body > center > table > tbody > tr:nth-child({}) > td:nth-child(3)'.format(i))

これで、daysの中に以下のように値がセットされます。

'body > center > table > tbody > tr:nth-child(1) > td:nth-child(3)'
'body > center > table > tbody > tr:nth-child(4) > td:nth-child(3)'
'body > center > table > tbody > tr:nth-child(7) > td:nth-child(3)'
...

次にlistをループさせます。
ループの中でまず、find_elements_by_css_selectorの引数にlistの値をセットしてseleniumオブジェクトを作成します。
これは日付の「選択」ボタンのオブジェクトになりますので、clickさせます。

そうすると、受付番号選択画面が表示されます。
そこで日付選択画面のときと同様にcss selectorの内容をlistに格納します。

    # 受付番号選択画面
    e = browser.find_elements_by_css_selector('body > center > table:nth-child(11) > tbody > tr > td')

    rec_nums = []
    # td:nth-child()の値 3から始まって4ずつ増加(3, 7, 11, ...)
    for i in range(3, int(len(e) / 2) * 4, 4):
        rec_nums.append('body > center > table:nth-child(11) > tbody > tr > td:nth-child({})'.format(i))

rec_numsは以下のような値がセットされます。

'body > center > table:nth-child(11) > tbody > tr > td:nth-child(3)'
'body > center > table:nth-child(11) > tbody > tr > td:nth-child(7)'
'body > center > table:nth-child(11) > tbody > tr > td:nth-child(11)'
...

さらにこのリストをループさせます。
前の画面と同じく、find_elements_by_css_selectorの引数にlistの値をセットしてseleniumオブジェクトを作成します。
これは受付番号の「選択」ボタンのオブジェクトになりますので、clickさせます。

これで購入履歴の画面まで到達できました。
あとは購入履歴の項目を一つずつprintで表示してみます。

無事、すべての要素を表示することができました。

あとは成形してDBに保存するだけです。
DBは何を使おうか迷ったのですが、MySQLを使う方向で考えています。

少しずつ初回版の完成に向かって進んでいます。
あと少しですね!

シェアする

  • このエントリーをはてなブックマークに追加

フォローする