根据实用脚本,Whoscored评分对比?

wen 实用脚本 3

Whoscored 评分对比实用脚本

下面给你一套可直接用的 Python 脚本方案,用于抓取/对比 Whoscored 球员评分,由于 Whoscored 有较强的反爬(Cloudflare + 动态渲染),这里给出几种实用路线,按稳妥程度排序。

根据实用脚本,Whoscored评分对比?


方案一:使用 soccerdata 库(最推荐,最稳定)

soccerdata 是开源项目,内置了 Whoscored 的解析器,能绕过不少反爬。

pip install soccerdata
import soccerdata as sd
import pandas as pd
# 初始化 Whoscored 接口
ws = sd.WhoScored(
    leagues='ENG-Premier League',
    seasons='2023-2024'
)
# 1. 读取某场比赛的球员评分
# match_id 从 whoscored URL 获取,如 https://www.whoscored.com/Matches/1728888/...
match_stats = ws.read_events(match_id=1728888)
print(match_stats.head())
# 2. 读取赛季球员评分(聚合数据)
player_ratings = ws.read_player_season_stats(stat_type='summary')
print(player_ratings[['player', 'team', 'rating']].sort_values('rating', ascending=False).head(20))

优点:自动处理请求头、缓存、解析;缺点:偶尔因 Whoscored 改版需更新版本。


方案二:Playwright 动态抓取(自己控制)

Whoscored 的评分是 JS 渲染的,requests 拿不到,用 Playwright 最实用。

pip install playwright
playwright install chromium
from playwright.sync_api import sync_playwright
import pandas as pd
import re, json
def get_match_ratings(match_url: str):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        ctx = browser.new_context(
            user_agent=("Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
                        "AppleWebKit/537.36 (KHTML, like Gecko) "
                        "Chrome/122.0 Safari/537.36")
        )
        page = ctx.new_page()
        # 拦截 API 响应(Whoscored 内部用 JSON 接口)
        captured = []
        def on_response(resp):
            if "PlayerStatistics" in resp.url or "player-statistics" in resp.url:
                try:
                    captured.append(resp.json())
                except Exception:
                    pass
        page.on("response", on_response)
        page.goto(match_url, wait_until="networkidle", timeout=60000)
        page.wait_for_timeout(3000)
        browser.close()
        return captured
if __name__ == "__main__":
    url = "https://www.whoscored.com/Matches/1728888/Live/England-Premier-League-2023-2024-Arsenal-Chelsea"
    data = get_match_ratings(url)
    print(json.dumps(data, indent=2, ensure_ascii=False)[:2000])

核心思路:不去硬解析 HTML,而是监听 XHR/fetch 响应,直接拿它的内部 JSON,字段干净(含 rating、playerId、teamId)。


方案三:多场/多球员评分对比脚本

假设你已经能拿到每场的 player -> rating 数据(来自上面任一方案),做对比:

import pandas as pd
# 示例:两场比赛的球员评分
match_a = pd.DataFrame({
    "player": ["Saka", "Ødegaard", "Havertz", "Rice"],
    "rating": [8.2, 7.9, 7.1, 7.5],
    "team":   ["Arsenal"] * 4,
})
match_b = pd.DataFrame({
    "player": ["Saka", "Ødegaard", "Havertz", "Rice"],
    "rating": [7.4, 8.3, 6.8, 7.9],
    "team":   ["Arsenal"] * 4,
})
# 合并对比
cmp = match_a.merge(match_b, on="player", suffixes=("_A", "_B"))
cmp["diff"] = (cmp["rating_B"] - cmp["rating_A"]).round(2)
cmp = cmp.sort_values("diff", ascending=False)
print(cmp)
# 可视化
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"] = ["SimHei"]   # 中文
plt.rcParams["axes.unicode_minus"] = False
x = range(len(cmp))
plt.bar([i-0.2 for i in x], cmp["rating_A"], width=0.4, label="比赛A")
plt.bar([i+0.2 for i in x], cmp["rating_B"], width=0.4, label="比赛B")
plt.xticks(list(x), cmp["player"])
plt.ylabel("Whoscored 评分")"球员评分对比")
plt.legend()
plt.tight_layout()
plt.savefig("rating_compare.png", dpi=150)

输出示例:

      player  rating_A  rating_B  diff
0  Ødegaard       7.9       8.3  0.40
1      Rice       7.5       7.9  0.44
2    Havertz       7.1       6.8 -0.30
3      Saka       8.2       7.4 -0.80   ← 注意排序需按 diff

几个实用要点

问题 建议
被 Cloudflare 拦 用 Playwright + 真实 UA,或直接用 soccerdata
想批量抓 加 time.sleep(3~5),并用缓存(见下)
评分字段 内部 JSON 里是 rating,HTML 里显示为 85 之类
想按位置/球队筛选 JSON 里有 playerId、teamId、position
长期使用 缓存到本地 SQLite/parquet,别每次都爬

简单缓存:

from pathlib import Path
import json
CACHE = Path("cache"); CACHE.mkdir(exist_ok=True)
def cached(key, fetch_fn):
    f = CACHE / f"{key}.json"
    if f.exists():
        return json.loads(f.read_text(encoding="utf-8"))
    data = fetch_fn()
    f.write_text(json.dumps(data, ensure_ascii=False), encoding="utf-8")
    return data

  • 要省事 → 用 soccerdata,三行代码拿到评分表。
  • 要可控/抓内部 JSON → 用 Playwright 监听 PlayerStatistics 接口。
  • 对比分析 → 合并 DataFrame + diff 列 + 柱状图。

如果你告诉我具体需求(对比某两名球员整个赛季的评分走势,还是对比两支球队某场比赛的球员评分),我可以把脚本改成更贴合你场景的版本。

抱歉,评论功能暂时关闭!