主に自分のメモ用途。

自分のためのメモ帳です。

kaggleコンペのタイトル取得(追記:他のデータも取得するようにした。)

kaggleコンペについての参加者の取り組み(コメントとか、機械学習関係のコードとか)を調査研究しようと思い、
ひとまず、コンペのタイトルを取得するコードを書いた。
このページの下部にも記載したし、以下のGitHubにも記載している。
Python_code/code to get kaggle competition titles at master · gotzy/Python_code · GitHub

また、後述しているが、タイトル以外の他のデータ(説明文、締切、カテゴリー、賞金、チーム数、タグ)も取得するバージョンも作った。具体的には、以下のGitHubを参照のこと。
Python_code/code to get kaggle competition titles and so on at master · gotzy/Python_code · GitHub


OSはMac, 言語はPython3, 主要フレームワークとしてSelenium、driverはChromeDriverを使っている。
TwitterAPIの存在を知ったが、Selenium使ったほうが自由度は高い。サイトアクセスの紳士協定(頻度や回数)には気をつける必要があるが。→やりすぎると"too many requests"と出てしばらくアクセスできなくなる。

仕様のポイントは、

  • タイトルをテキストデータで取得
  • 選択制で、印刷やPDF保存なども可能(「印刷機の選択」と「印刷実行」のボタン押下は手動)

なお、ユーザには関係ないことだが開発側として言及しておくと、
当該ページはスクロールバーが下に下がって少しずつコンテンツが出てくるものなので、
「下にスクロールしてページソースを取得更新しページソースの情報量が変化しなくなるところでスクロールし切ったと判定し、スクロールするのを終了する」ことで、
当該ページに対応できるようにした。

タイトル以外の他のデータが欲しい場合は、
XPathを調べて(Google Chromeなどのデベロッパーツールなどで調べられる)
タイトルと同様に、find_element_by_xpath()などで取得すればよい。
(追記:一部は、find_element_by_xpath()ではなく、find_element_by_css_selector()で取得しないといけない。XPathが長すぎるのが原因かも。)
もしくは、page_sourceメソッドでページソースを取得して、正規表現などで必要な要素を抽出してもよい。
追記:タイトル以外の他のデータ(説明文、締切、カテゴリー、賞金、チーム数、タグ)も取得するバージョンも作った。具体的には、以下のGitHubを参照のこと。
Python_code/code to get kaggle competition titles and so on at master · gotzy/Python_code · GitHub


データ取得してみて思ったけど、
20180924現在まで(約8年間)に、約300タイトル出てるんだなあと。
また、kaggle立ち上げ当時は、賞金も参加チームも少なめだなあと。

from selenium import webdriver
from time import sleep
import datetime

try:
    yn01=input("テキスト抽出だけでなく、pdf印刷もしますか? (y or n) : ")
except:
    sleep_time=0
if yn01=='y':
    sleep_time=5
else:
    sleep_time=0
    

t1 = datetime.datetime.now()
date_time01='{0:04d}'.format(t1.year)+'{0:02d}'.format(t1.month)+'{0:02d}'.format(t1.day)+"_"+'{0:02d}'.format(t1.hour)+'{0:02d}'.format(t1.minute)+'{0:02d}'.format(t1.second)

sleep(5)

driver = webdriver.Chrome() 

driver.set_window_size(600, 700)  

driver.get('https://www.kaggle.com/competitions')
sleep(10)

driver.set_window_position(100,50)

html01=driver.page_source
while 1:
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    sleep(15) #この数値が小さすぎると、2行下の判定で誤判定が起こり、最後までスクロールできない。
    html02=driver.page_source
    if html01!=html02:
        html01=html02
    else:
        break

#ディレクトリ名やファイル名は適宜変更してください。
with open("/Users/username/kaggle_competition_titles_"+date_time01+".txt","w") as f:
    cnt01=0
    error_cnt=0
    while 1:
        try:
            title01=driver.find_element_by_xpath('/html/body/div[1]/div[2]/div/div/div[2]/div/div[1]/div[2]/div[2]/div/div/div['+str(cnt01)+']/div/div/div[1]/a').text
            print(cnt01-1,": ",title01)
            print('{0:04d}'.format(cnt01-1),": ",title01,file=f)
        except:
            error_cnt+=1
            if error_cnt > 30:
                break
        cnt01+=1        
        
if sleep_time >=1:
    print("\npdfを選んで、印刷(pdf保存)してください。印刷後、ブラウザを閉じます。\n")
    driver.execute_script('window.print();')
sleep(sleep_time)

driver.close()

t2 = datetime.datetime.now()
print(t2-t1)

sleep(2)