用 Python 写一个 Kaggle 比赛排行榜的爬虫

长久以来,我和小伙伴们都被 Kaggle 网站的加载速度困扰着,比如最近在用 Kaggle 上的数据集测试模型效果时,遇到排行榜(Leaderboard)刷新困难的问题。于是我们开始探索解决方案。

首先尝试直接使用页面链接进行数据爬取,很明显爬不到,因为 Kaggle 的数据是异步响应的。于是我打开 Leaderboard 页面的开发者工具,以著名的 Titanic 竞赛的排行榜为例,打开 Network 选项,查看 XHR 项,然后 ctrl+R 刷新页面,可以看到如下列表:

我用红框圈起来的这个就是我们要找的排行榜数据,点击它后可以看到它的 Request URL 如下:

然后把这个链接复制到浏览器打开,就可以看到一大段 JSON 形式的排行榜数据:

这里推荐使用在线 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 文件存到本地啦。


分享更多关于数据挖掘的有趣内容,欢迎大家关注公众号哦:

发布了38 篇原创文章 · 获赞 23 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/cyan_soul/article/details/103218008
今日推荐