本文目录导读:

这是一个非常实用且有趣的数据分析问题,要回答“谁更忙”,我们需要先定义一个“忙”的标准化口径,然后通过脚本去抓取或处理数据。
单纯看“扑救次数”往往不全面,因为门将面对弱旅可能全场无事可做(0扑救),面对强队可能被射30脚(虽败犹荣)。
以下是针对不同数据来源(API、Excel/CSV、即时抓取)的实用脚本方案。
基于 Python + 免费 API(最推荐,适合联赛统计)
这个方案使用 requests 库调用开放API(以 api-football 为例,需免费Token),计算“场均高强度扑救”和“射正/扑救比”,来评估谁是真正的“忙碌先生”。
核心逻辑: 忙碌度 = 扑救次数 (Saves) + 击出球 (Punches) + 出击解围 (High Claims),再除以 比赛场次,同时参考 失球数。
import requests
import json
from statistics import mean
# 1. 配置(请替换为你的API Token)
API_KEY = "你的_free_token"
HEADERS = {"x-apisports-key": API_KEY}
# 以2023-2024赛季英超为例
LEAGUE_ID = 39
SEASON = "2023"
def get_standings():
"""获取球队ID列表"""
url = f"https://v3.football.api-sports.io/standings?league={LEAGUE_ID}&season={SEASON}"
resp = requests.get(url, headers=HEADERS).json()
teams = []
if resp.get("results"):
for team_info in resp["response"][0]["league"]["standings"][0]:
teams.append({"id": team_info["team"]["id"], "name": team_info["team"]["name"]})
return teams
def get_goalkeeper_stats(team_id):
"""获取该队门将的详细扑救数据(需按球员搜索)"""
# 方法:获取球队球员,筛选位置为Goalkeeper
url = f"https://v3.football.api-sports.io/players?team={team_id}&season={SEASON}"
resp = requests.get(url, headers=HEADERS).json()
gk_stats = {}
if resp.get("results"):
for player in resp["response"]:
p = player["player"]
stat = player["statistics"][0]
if stat["games"]["position"] == "Goalkeeper":
# 关键指标抓取
gk_stats["name"] = p["name"]
gk_stats["saves"] = stat.get("goals", {}).get("saves", 0) # 扑救
gk_stats["conceded"] = stat.get("goals", {}).get("conceded", 0)
gk_stats["matches"] = stat.get("appearences", 0) # 出场
gk_stats["clean_sheets"] = stat.get("clean_sheet", 0)
gk_stats["punches"] = stat.get("penalty", {}).get("saved", 0) # 示意,真实字段可能不同
# 防止API字段差异,这里做安全get
break # 只取主力门将
return gk_stats
def analyze(team_name):
"""主分析函数"""
teams = get_standings()
target = next((t for t in teams if t["name"] == team_name), None)
if not target:
return None
stats = get_goalkeeper_stats(target["id"])
if not stats or stats["matches"] == 0:
return None
# 核心忙碌指数计算:每90分钟扑救数 + 失球数(失球越多越忙,因为面对压力大)
busy_index = (stats["saves"] + stats["conceded"]) / stats["matches"]
return {
"team": team_name,
"player": stats["name"],
"总扑救": stats["saves"],
"场均扑救": round(stats["saves"] / stats["matches"], 2),
"总失球": stats["conceded"],
"忙碌指数": round(busy_index, 2)
}
if __name__ == "__main__":
# 示例:对比两队门将
for team in ["Manchester City", "Luton"]:
result = analyze(team)
print(json.dumps(result, ensure_ascii=False, indent=2))
基于 CSV/Excel 历史数据(适合分析师)
如果你手头有包含“射正”、“扑救”、“失球”的表格,可以用 Pandas 快速算出“扑救率”和“场均扑救”。
import pandas as pd
# 假设你有一个goalkeeper_stats.csv,包含列:Player, Team, Saves, GoalsConceded, ShotsOnTarget, MatchesPlayed
df = pd.read_csv("gk_data.csv")
# 1. 基础筛选:只保留出场超过10场的门将(避免偶然性)
df = df[df["MatchesPlayed"] >= 10]
# 2. 计算核心指标
# 扑救率:扑救 / 射正(射正包含被扑出和进球)
df["Save_Percentage"] = df["Saves"] / (df["Saves"] + df["GoalsConceded"]) * 100
# 忙碌程度:场均面对射正数(射正门将是不可能无视的)
df["Shots_Confronted_Per_Game"] = (df["Saves"] + df["GoalsConceded"]) / df["MatchesPlayed"]
# 3. 排序输出
# 谁是“最忙”?——场均面对射正最多的
busiest = df.sort_values("Shots_Confronted_Per_Game", ascending=False).head(10)
print("忙碌榜(场均面对射正):")
print(busiest[["Player", "Team", "Shots_Confronted_Per_Game", "Save_Percentage"]])
# 4. 额外分析:谁是“被射多但扑得也多”的高危门将(典型弱队门神)
print("\n扑救绝对次数最高(但可能说明防线差):")
print(df.sort_values("Saves", ascending=False).head(5)[["Player", "Team", "Saves"]])
网页即时抓取(针对特定比赛)
如果你想在赛后5分钟知道谁更忙,可以用 requests + BeautifulSoup 抓取SofaScore或FlashScore。
# 简单示例(伪代码,需处理动态加载)
import requests
from bs4 import BeautifulSoup
def fetch_match_stats(match_url):
r = requests.get(match_url, headers={"User-Agent": "Mozilla/5.0"})
soup = BeautifulSoup(r.text, "html.parser")
# 以SofaScore为例,数据在JSON里,这里用正则提取(简化版)
data = soup.find("script", {"id": "__NEXT_DATA__"}).string
import json
json_data = json.loads(data)
# 找到门将的扑救统计(路径因网站而异)
home_gk = json_data['props']['pageProps']['match']['homeTeam']['goalkeepers'][0]
away_gk = json_data['props']['pageProps']['match']['awayTeam']['goalkeepers'][0]
return (f"{home_gk['name']}: {home_gk['saves']}扑救, {home_gk['goalsConceded']}失球",
f"{away_gk['name']}: {away_gk['saves']}扑救, {away_gk['goalsConceded']}失球")
# 使用示例
# print(fetch_match_stats("https://www.sofascore.com/team/football/2024"))
谁更忙”的结论标准
- 绝对扑救数:适合判断门将的工作量(但可能因为防线失位导致)。
- 场均扑救数:最常用的“忙碌”指标。场均扑救 > 4.0 的通常是被射成筛子的“射正王”,场均扑救在 2-3 次 属于中上游球队的稳定门将。
- 扑救成功率:这个不是衡量“忙”,而是衡量“忙中不出错”,如果有人场均被射10次且扑出9个,那他比一个场均被射1次扑出1个的更“值得MVP”。
总结脚本输出逻辑建议: 无论用哪种脚本,最终建议在输出时排序优先级为:
场均扑救 > 场均失球 > 扑救成功率
这样可以精准找出那些“虽然丢球多但其实是我方防线太坑”的最忙碌门将。
如果你有具体的联赛数据源或文件,可以发一下结构,我可以帮你写精准的匹配脚本。