競馬予想モデルを作るうえでseleniumを使ったスクレイピングを学んだ。

#はじめに
　
　前回に引き続きnetkeiba.comからの競馬データを使って予想プログラムを作っています。予想プログラムを作ることより、スクレイピングの内容が学べましたので備忘でまとめます。

>Pandasを使って競馬のデータベースを取得してみた
https://qiita.com/Fumio-eisan/items/1c1c429746a3a0add055


競馬予想プログラム自体はこちらの方の動画を御覧ください。非常に丁寧に解説されており、初学者でも十分に理解することができます。

>競馬予想で始めるデータ分析・機械学習
https://www.youtube.com/channel/UCDzwXAWu1zIfJuPTTZyWthw


##javascriptで書かれている場所のスクレイピング（Selenimum活用）

　`html`から出走表や馬名、騎手などの情報を取る際に`pandas`を活用して取得できることは前回まとめました。これだけでは十分でない場合があります。`javascript`で記述されている部分に関しては、スクレイピングに一手間掛ける必要があります。


###Seleniumとは
　`Selenium`とはWebブラウザの操作を自動化するためのフレームワークになります。`Chrome`でも`FireFox`でも、`IE`などでも使えるようです。今回は`Chrome`を使います。


http://chromedriver.chromium.org/downloads

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/d6936ce7-2cc8-4daf-0fbe-e734dd599459.png)

　こちらでお使いの`Chrome`バージョンの`selenium`をダウンロードください。

```python
from selenium.webdriver import Chrome, ChromeOptions
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
```

###URLを開く

単純にURLを開く方法は下記です。

```python

options= ChromeOptions()
driver = Chrome(executable_path=r'(chromedriver.exe)のパスを指定下さい',options=options)
driver.get(url)
```

ここでは`choromedriver`の`path`を入れています。システム環境設定にて`choromedriver`の`path`を指定すればこのプログラム上での記述は要らないようなのですが、設定しても動作しませんでした。従い、わざわざ`executable_path`を指定しています。


###出走情報を取るクラス定義

 以下に出走情報をスクレイピングするクラスを定義します。`pandas`のデータフレームに入れてやります。

```python

from tqdm import tqdm_notebook as tqdm
import pandas as pd
import time

class ShutubaTable:
    def __init__(self):
        self.shutuba_table = pd.DataFrame()
    
    def scrape_shutuba_table(self, race_id_list):
        options= ChromeOptions()
        driver = Chrome(executable_path=r'C:\Users\lllni\Documents\Python\20200528_keiba\chromedriver_win32\chromedriver.exe',options=options)
        for race_id in tqdm(race_id_list):
            url = 'https://race.netkeiba.com/race/shutuba.html?race_id=' + race_id
            driver.get(url)
            elements = sample_driver.find_elements_by_class_name('HorseList')
            for element in elements:
                tds = element.find_elements_by_tag_name('td')
                row = []
                for td in tds:
                    row.append(td.text)
                    if td.get_attribute('class') in ['HorseInfo', 'Jockey']:
                        href = td.find_element_by_tag_name('a').get_attribute('href')
                        row.append(re.findall(r'\d+', href)[0])
                self.shutuba_table = self.shutuba_table.append(pd.Series(row, name=race_id))
        time.sleep(1)
        driver.close()

```

　ポイントとして、

1) 'HorseList`classにほしいデータが入っているので以下のように取り出す。

```python
elements = sample_driver.find_elements_by_class_name('HorseList')
```
　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/132b8528-ce53-381b-65bb-41597e8dc6a9.png)

2)`td`タグごとに馬名、オッズなどそれぞれの情報を取り出す。

```python
for element in elements:
　　tds = element.find_elements_by_tag_name('td')
　　row = []
　　for td in tds:
   　　row.append(td.text)
　　　 self.shutuba_table = self.shutuba_table.append(pd.Series(row, name=race_id))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/5ba4c336-ee38-8749-f483-2f9ef9829587.png)

この`td`タグをそれぞれ記載することで`javascript`で記載された情報も取り出すことができます。また、`element`は馬ごととなっています。つまり、馬が変わるごとに`row`は空になって`td`タグの情報がまた一から入れることができるのです。

　

###インスタンス化して読み込む

```python
st = ShutubaTable1()
sample_driver = Chrome(executable_path=r'C:\Users\lllni\Documents\Python\20200528_keiba\chromedriver_win32\chromedriver.exe',options=options)
sample_driver.get(url
st.scrape_shutuba_table(['202005030211'])#予想したいrace_idを入れる
st.shutuba_table

```

レースidは`netkeiba.com`であれば出走表のURLの末尾に数値が入っていますので、見たいレースidの数値だけ取り出して貼ってください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/078b9e72-2f0d-f763-48c4-7f024fe528f2.png)

無事に取り出すことができました。


#終わりに

　スクレイピングについてまた一つ理解が深まりました。