天天看點

用 Python 寫一個 Kaggle 比賽排行榜的爬蟲

長久以來,我和小夥伴們都被 Kaggle 網站的加載速度困擾着,比如最近在用 Kaggle 上的資料集測試模型效果時,遇到排行榜(Leaderboard)重新整理困難的問題。于是我們開始探索解決方案。

首先嘗試直接使用頁面連結進行資料爬取,很明顯爬不到,因為 Kaggle 的資料是異步響應的。于是我打開 Leaderboard 頁面的開發者工具,以著名的 Titanic 競賽的排行榜為例,打開 Network 選項,檢視 XHR 項,然後 ctrl+R 重新整理頁面,可以看到如下清單:

用 Python 寫一個 Kaggle 比賽排行榜的爬蟲

我用紅框圈起來的這個就是我們要找的排行榜資料,點選它後可以看到它的 Request URL 如下:

用 Python 寫一個 Kaggle 比賽排行榜的爬蟲

然後把這個連結複制到浏覽器打開,就可以看到一大段 JSON 形式的排行榜資料:

用 Python 寫一個 Kaggle 比賽排行榜的爬蟲

這裡推薦使用線上 JSON 校驗格式化工具 Be JSON 來将這些資料重新排版,隻需要粘貼過去使用“格式化校驗”功能,就可以通過更好的排版方式來檢視資料了。然後我們很容易看出,整個結果是一個大的字典,裡面包含着小字典:

  • submissions:其中又包含若幹個小字典,每個字典存儲一個隊伍的資訊及其戰績,包括名次、隊名、分數、送出次數、最後一次送出時間等
  • beforeUser:包含前50名隊伍的資訊及戰績
  • afterUser:包含50名以後的全部隊伍資訊及戰績

而我們隻需要解析出 beforeUser 和 afterUser 中的資料就可以了,下面是具體的實作過程。

首先确定自己想要抓取 public 榜還是 private 榜,隻有已經結束的比賽才公開了 private 榜,否則隻能抓到 public 榜。具體抓資料代碼如下:

import urllib3  # pip install -i https://pypi.anaconda.org/pypi/simple urllib3

if type == 'public':
    url = 'https://www.kaggle.com/c/{competition}/leaderboard.json?includeBeforeUser=true&includeAfterUser=true'.format(
        competition=competition)
elif type == 'private':
    url = 'https://www.kaggle.com/c/{competition}/leaderboard.json?includeBeforeUser=true&includeAfterUser=true&type=private'.format(
        competition=competition)
else:
    print('榜單類型有誤,請檢查')

http = urllib3.PoolManager()
response = http.request('GET', url)
           

然後對抓取到的資料進行解析,取出我們需要的資訊,構成更易讀的 dataframe 形式:

import pandas as pd
import json

ranks0 = str(response.data).replace("\\", "")
ranks1 = json.loads(ranks0[2:-1])['beforeUser']
ranks2 = json.loads(ranks0[2:-1])['afterUser']

ranks = ranks1 + ranks2

team_list = list(ranks)

rank_score = pd.DataFrame(columns=['rank', 'teamName', 'entries', 'lastSubmission', 'score'])

for team in team_list:
    rank = team.get('rank')
    teamName = team.get('teamName')
    entries = team.get('entries')
    lastSubmission = team.get('lastSubmission')
    score = team.get('score')
    rank_score = rank_score.append(
        {'rank': rank, 'teamName': teamName, 'entries': entries, 'lastSubmission': lastSubmission, 'score': score},
        ignore_index=True)

rank_score
           

至此,我們就得到一個比賽的全部排行榜資料啦,封裝好的代碼請移步 Github,下載下傳項目後直接在指令行執行:

python main.py titanic private
           

python main.py titanic public
           

就可以把排行榜資料作為 csv 檔案存到本地啦。

分享更多關于資料挖掘的有趣内容,歡迎大家關注公衆号哦:

用 Python 寫一個 Kaggle 比賽排行榜的爬蟲