Whoscored 评分对比案例(Python)
下面用 Python 演示如何对比不同球员的 Whoscored 评分,包含数据构建、可视化、统计对比三步。

数据准备
Whoscored 没有公开 API,实际项目中通常用 requests + BeautifulSoup 抓取,或使用 soccerdata、ScraperFC 等库,这里先用模拟数据演示分析逻辑。
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 模拟 Whoscored 评分数据(近 5 场比赛)
data = {
"球员": ["梅西", "梅西", "梅西", "梅西", "梅西",
"姆巴佩", "姆巴佩", "姆巴佩", "姆巴佩", "姆巴佩",
"哈兰德", "哈兰德", "哈兰德", "哈兰德", "哈兰德"],
"对手": ["A队", "B队", "C队", "D队", "E队"] * 3,
"评分": [8.5, 9.1, 7.8, 8.9, 9.3,
7.9, 8.2, 8.6, 7.5, 8.8,
8.1, 7.6, 8.9, 8.4, 7.2],
}
df = pd.DataFrame(data)
print(df.head())
基础统计对比
stats = df.groupby("球员")["评分"].agg(
场次="count",
平均评分="mean",
最高评分="max",
最低评分="min",
标准差="std"
).round(2)
print(stats)
示例输出:
场次 平均评分 最高评分 最低评分 标准差
哈兰德 5 8.04 8.9 7.2 0.66
姆巴佩 5 8.20 8.8 7.5 0.50
梅西 5 8.72 9.3 7.8 0.61
可视化对比
① 折线图:各球员逐场评分走势
plt.figure(figsize=(10, 5))
sns.lineplot(data=df, x="对手", y="评分", hue="球员", marker="o")"Whoscored 逐场评分对比")
plt.ylabel("评分")
plt.grid(alpha=0.3)
plt.show()
② 箱线图:评分分布对比
plt.figure(figsize=(8, 5)) sns.boxplot(data=df, x="球员", y="评分")"评分分布对比") plt.show()
③ 柱状图:平均评分
plt.figure(figsize=(8, 5))
sns.barplot(data=df, x="球员", y="评分", estimator="mean", errorbar=None)"平均评分对比")
plt.ylabel("平均评分")
plt.show()
进阶:显著性检验
若想知道球员之间评分差异是否具有统计显著性:
from scipy import stats
messi = df[df["球员"] == "梅西"]["评分"]
mbappe = df[df["球员"] == "姆巴佩"]["评分"]
t, p = stats.ttest_ind(messi, mbappe, equal_var=False)
print(f"t = {t:.3f}, p = {p:.4f}")
if p < 0.05:
print("两人评分存在显著差异")
else:
print("两人评分差异不显著")
实战:抓取 Whoscored 数据(思路)
Whoscored 有反爬(Cloudflare + JS 加密),直接 requests 拿不到,常见方案:
# 方案A:使用 soccerdata 库
# pip install soccerdata
import soccerdata as sd
ws = sd.WhoScored(leagues="ENG-Premier League", seasons="2023-2024")
ratings = ws.read_player_match_ratings(match_id="xxxxxxxx")
print(ratings.head())
# 方案B:ScraperFC
# pip install ScraperFC
from ScraperFC import WhoScored
ws = WhoScored()
df = ws.scrape_player_match_stats(league="Premier League",
season="2023-2024",
match_id="xxxx")
⚠️ Whoscored 使用条款限制自动化抓取,建议仅用于学习并遵守其 robots.txt。
完整分析脚本整合
def compare_players(df, players):
sub = df[df["球员"].isin(players)]
# 统计
stats = sub.groupby("球员")["评分"].agg(["mean", "max", "min", "std"]).round(2)
print("=== 统计数据 ===")
print(stats)
# 可视化
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
sns.lineplot(data=sub, x="对手", y="评分", hue="球员", marker="o", ax=axes[0])
axes[0].set_title("逐场走势")
sns.boxplot(data=sub, x="球员", y="评分", ax=axes[1])
axes[1].set_title("分布对比")
plt.tight_layout()
plt.show()
return stats
compare_players(df, ["梅西", "姆巴佩", "哈兰德"])
- Whoscored 评分本质是 0–10 的连续变量,适合用均值 + 分布 + 走势三个维度对比。
- 想量化判断差距是否“真实”,可用 t 检验 / ANOVA。
- 生产环境建议用
soccerdata或ScraperFC抓取,别自己硬爬。
需要我改成具体某两个球员、某赛季的真实数据抓取版本吗?