东京奥运会已经圆满结束,中国金牌榜惜居第二,与美国只有一步之遥。
今年奥运是特殊的一年,中美日三方之间的关系不言而喻,从结果就可以隐隐看出,中美金牌之间的争斗非常激烈。于是顺手做了一张可视化图表,看一看中美之间的金牌追逐战全过程,先上图为敬。(动图大小超过上传限制)
一句话原理
利用爬虫技术,在线爬取所有参赛国家每天的金银铜牌数,存到csv文件中,再利用matplotlib根据时间制作可视化图表。
数据获取(各国名称和ID)
数据源选择的是百度奥运专栏,通过F12找到了数据获取接口,再将数据进行清洗保存,这也是这个项目的主要工作量。
随意打开一个国家的奖牌详情,url中包含了一个country_id,所以得先找到所有国家的id才行。
https://tiyu.baidu.com/tokyoly/delegation/8705/tab/奖牌明细
要找id就要先找到哪里可以看到所有国家的名称页面,这样就可以获取到国家名称和id的对应关系。点击奖牌榜“更多”,页面元素可以满足需求。
打开奖牌榜“更多”,找到对应的接口。由于此接口返回的是html,因此需要进一步的数据清洗。即匹配国家的id和name,使用re.findall(pat, response)找出所有匹配项。
https://tiyu.baidu.com/tokyoly/home/tab/奖牌榜/from/pc
数据获取(各国奖牌数)
获取到id后,就可以查询奖牌数了,利用上面讲的url,返回也是一个html,进一步进行数据清洗,获取到时间和奖牌数的对应关系。
但是返回的数据中,由于页面中也有每项项目的奖牌详情,因此后面的数据是不需要关注的(图中3根红线之前的代表金银铜牌详情),需要去除。这边也有个注意点,不是每个国家都有金银铜奖牌的,因此这边匹配的时候要注意一下。
数据存储
经过上述数据清洗后,已经整齐一致,接下来就是保存到csv文件中,为后面的可视化做好准备。
可视化呈现
生成上面的可视化图表,采用的是pandas_alive库,几行代码轻松搞定。
def chart_create(self):
try:
covid_df = pd.read_csv('medals_gold.csv', index_col=0, parse_dates=[0])
covid_df.plot_animated(filename='medals_gold.gif', n_visible=15)
except Exception as e:
print(e)
这样执行时,可能会有一些调用matplotlib的一些警告,不影响结果生成,目前还没研究怎么去解决,有兴趣的盆友可以交流指导一下。
UserWarning: FixedFormatter should only be used together with FixedLocator
ax.set_yticklabels(self.df.columns)
UserWarning: FixedFormatter should only be used together with FixedLocator
ax.set_xticklabels([max_val] * len(ax.get_xticks()))
UserWarning: Animation was deleted without rendering anything. This is most likely unintended. To prevent deletion, assign the Animation to a variable that exists for as long as you need the Animation.
warnings.warn(
总结
这个项目涉及到爬虫和数据处理技术,其中涉及正则的匹配清洗,文件保存,pandas文件处理,matplotlib图表生成。
Python新手可以举一反三,做一个奖牌总数的动态图,满满的成就感有没有。有兴趣的盆友,请评论留言交流,多多点赞,共同进步。
中国加油!