Whoscored评分对比 — Python案例分析
下面我用一个完整的Python案例,演示如何对比两名球员(或两支球队)在Whoscored上的评分数据,由于Whoscored有反爬机制,实际抓取需要处理,这里重点演示数据处理与可视化对比的完整流程。

场景设定
假设我们要对比 梅西 vs C罗 在某一赛季的Whoscored评分表现,包含:
- 场均评分
- 各维度评分(进攻、传球、防守等)
- 评分分布
数据准备(模拟Whoscored数据结构)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
# 解决中文显示
matplotlib.rcParams['font.sans-serif'] = ['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False
# 模拟Whoscored风格的数据(实际可用requests+BeautifulSoup抓取)
data = {
'球员': ['梅西']*10 + ['C罗']*10,
'比赛场次': list(range(1, 11)) * 2,
# Whoscored 单场评分(6.0 - 10.0)
'评分': [8.5, 9.1, 7.8, 8.9, 9.3, 8.2, 7.9, 9.0, 8.7, 8.4,
7.6, 8.1, 7.2, 8.5, 7.9, 9.2, 6.8, 8.0, 7.5, 8.3],
# 关键维度评分(Whoscored 六大类)
'进攻': [8.7, 9.4, 7.5, 9.0, 9.5, 8.0, 7.8, 9.1, 8.6, 8.5,
8.2, 8.5, 7.0, 9.1, 8.0, 9.4, 6.5, 8.2, 7.8, 8.6],
'传球': [9.0, 9.2, 8.3, 9.1, 9.4, 8.6, 8.2, 9.2, 8.9, 8.8,
7.0, 7.8, 6.5, 8.2, 7.5, 8.5, 6.2, 7.6, 7.0, 7.9],
'防守': [6.5, 6.8, 6.2, 6.7, 6.9, 6.4, 6.3, 6.8, 6.6, 6.5,
6.0, 6.5, 5.8, 6.8, 6.2, 7.0, 5.5, 6.3, 6.0, 6.4],
}
df = pd.DataFrame(data)
print(df.head())
核心对比分析
基础统计对比
summary = df.groupby('球员')['评分'].agg(['mean', 'std', 'max', 'min'])
summary.columns = ['场均评分', '评分波动', '最高分', '最低分']
print(summary.round(2))
输出示例:
场均评分 评分波动 最高分 最低分
球员
C罗 7.91 0.71 9.2 6.8
梅西 8.58 0.51 9.3 7.8
梅西场均评分更高且波动更小,稳定性更强。
各维度评分雷达图对比
from math import pi
dims = ['进攻', '传球', '防守']
mei = df[df['球员']=='梅西'][dims].mean().values
cr = df[df['球员']=='C罗'][dims].mean().values
angles = [n / len(dims) * 2 * pi for n in range(len(dims))]
angles += angles[:1] # 闭合
fig, ax = plt.subplots(figsize=(6, 6), subplot_kw=dict(polar=True))
for values, name, color in [(mei, '梅西', 'blue'), (cr, 'C罗', 'red')]:
vals = list(values) + values[:1]
ax.plot(angles, vals, 'o-', linewidth=2, label=name, color=color)
ax.fill(angles, vals, alpha=0.15, color=color)
ax.set_xticks(angles[:-1])
ax.set_xticklabels(dims)
ax.set_ylim(5, 10)
ax.set_title('各维度评分雷达图对比', pad=20)
ax.legend(loc='upper right')
plt.tight_layout()
plt.savefig('radar_compare.png', dpi=150)
plt.show()
评分趋势折线对比
plt.figure(figsize=(10, 5))
for player, color in [('梅西','blue'), ('C罗','red')]:
sub = df[df['球员']==player]
plt.plot(sub['比赛场次'], sub['评分'], 'o-', label=player, color=color)
plt.axhline(y=df['评分'].mean(), color='gray', linestyle='--', label='总体均值')
plt.xlabel('比赛场次')
plt.ylabel('Whoscored 评分')'单场评分趋势对比')
plt.ylim(6, 10)
plt.legend()
plt.grid(alpha=0.3)
plt.tight_layout()
plt.savefig('trend_compare.png', dpi=150)
plt.show()
评分分布箱线图
plt.figure(figsize=(7, 5))
df.boxplot(column='评分', by='球员', patch_artist=True,
boxprops=dict(facecolor='lightblue'))'评分分布箱线图')
plt.suptitle('')
plt.ylabel('评分')
plt.tight_layout()
plt.show()
箱线图能直观显示中位数、四分位区间、异常值,比均值更能反映稳定性。
评分差值统计(逐场对比)
pivot = df.pivot_table(index='比赛场次', columns='球员', values='评分')
pivot['差值(梅西-C罗)'] = pivot['梅西'] - pivot['C罗']
print(pivot.round(2))
print(f"\n梅西胜出场次: {(pivot['差值(梅西-C罗)']>0).sum()}")
print(f"平均领先分差: {pivot['差值(梅西-C罗)'].mean():.2f}")
真实抓取Whoscored的要点(补充)
Whoscored 使用 Cloudflare 反爬,直接 requests 常被拦截,可行方案:
# 方案1:Selenium + 手动登录Cookie
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('--disable-blink-features=AutomationControlled')
driver = webdriver.Chrome(options=options)
driver.get('https://www.whoscored.com/Players/xxxxx/Show/Lionel-Messi')
# 方案2:使用 requests + 浏览器复制的 Cookie
import requests
headers = {
'User-Agent': 'Mozilla/5.0 ...',
'Cookie': '你的cookie字符串'
}
resp = requests.get(url, headers=headers)
⚠️ 注意:遵守网站 robots.txt 与使用条款,仅用于个人学习研究,控制请求频率。
完整对比结论模板
| 指标 | 梅西 | C罗 | 优者 |
|---|---|---|---|
| 场均评分 | 58 | 91 | 梅西 |
| 评分稳定性(σ) | 51 | 71 | 梅西 |
| 进攻维度 | 79 | 23 | 梅西 |
| 传球维度 | 87 | 42 | 梅西 |
| 防守维度 | 57 | 25 | 梅西 |
| 单场胜出 | 8场 | 2场 | 梅西 |
该案例展示了 pandas 数据聚合 → matplotlib 多维可视化(雷达图/折线/箱线)→ 统计结论的完整分析链路,若你有具体球员ID或真实数据文件,我可以帮你改写为针对性的抓取+分析脚本,需要我补充哪部分(如真实爬虫代码、球队对比、或者按位置分组分析)?