PHP 项目:WhoScored 评分对比
你想做一个 WhoScored 评分对比的 PHP 项目,我帮你梳理一个完整的实现方案。

需求理解
从 WhoScored 抓取球员/球队评分数据,做对比展示,核心模块:
- 数据采集(抓取 WhoScored 评分)
- 数据存储(MySQL 缓存评分数据)
- 对比展示(多球员/多球队评分图表对比)
技术栈建议
| 用途 | 推荐 |
|---|---|
| 后端 | PHP 8.x + Composer |
| HTTP 抓取 | GuzzleHttp |
| HTML 解析 | symfony/dom-crawler(WhoScored 数据靠 JS 渲染,最好找 API) |
| 数据库 | MySQL / SQLite |
| 前端图表 | Chart.js / ECharts |
| 框架 | Laravel 或纯 PHP(视规模) |
WhoScored 数据获取要点
WhoScored 反爬较强,官方页面数据由 JS 动态加载。推荐走其内部 API:
https://www.whoscored.com/StatisticsFeed/1/GetPlayerStatistics
?category=summary
&subcategory=all
&statsAccumulationType=0
&isCurrent=true
&isMinApp=true
&page=1
&includeZero=false
&sortBy=Rating
&field=Overall
&teamId=
&playerId=
&stageId=
&tournamentOptions=
&stageId=
关键点:
- 必须带 正确的
Referer和User-Agent,否则返回 403 - 请求频率要低,建议加延时 + 缓存
- 部分接口需要 Cookie(首次访问首页获取)
核心代码示例
抓取球员评分(Guzzle)
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
class WhoScoredScraper
{
private Client $client;
public function __construct()
{
$this->client = new Client([
'base_uri' => 'https://www.whoscored.com/',
'timeout' => 20,
'headers' => [
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
. 'AppleWebKit/537.36 (KHTML, like Gecko) '
. 'Chrome/120.0 Safari/537.36',
'Referer' => 'https://www.whoscored.com/',
'Accept' => 'application/json, text/javascript, */*; q=0.01',
'X-Requested-With' => 'XMLHttpRequest',
],
]);
}
public function getPlayerStats(int $page = 1, string $sortBy = 'Rating'): array
{
$res = $this->client->get('StatisticsFeed/1/GetPlayerStatistics', [
'query' => [
'category' => 'summary',
'subcategory' => 'all',
'statsAccumulationType' => 0,
'isCurrent' => 'true',
'isMinApp' => 'true',
'page' => $page,
'includeZero' => 'false',
'sortBy' => $sortBy,
'field' => 'Overall',
],
]);
return json_decode($res->getBody()->getContents(), true)['playerTableStats'] ?? [];
}
}
数据库表结构
CREATE TABLE players (
id INT PRIMARY KEY AUTO_INCREMENT,
ws_player_id INT UNIQUE,
name VARCHAR(100),
team VARCHAR(100),
position VARCHAR(20),
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE ratings (
id INT PRIMARY KEY AUTO_INCREMENT,
player_id INT,
rating DECIMAL(3,2),
minutes INT,
goals INT,
assists INT,
season VARCHAR(20),
recorded_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (player_id) REFERENCES players(id),
INDEX (player_id, season)
);
评分对比控制器
class CompareController
{
public function compare(array $playerIds): array
{
$in = implode(',', array_map('intval', $playerIds));
$sql = "SELECT p.name, p.team, r.rating, r.goals, r.assists
FROM players p
JOIN ratings r ON r.player_id = p.id
WHERE p.id IN ($in) AND r.season = '2024'
ORDER BY r.rating DESC";
return $this->db->query($sql)->fetchAll();
}
}
前端对比图(Chart.js)
<canvas id="cmp"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
fetch('/api/compare?ids=1,2,3')
.then(r => r.json())
.then(data => {
new Chart(document.getElementById('cmp'), {
type: 'radar',
data: {
labels: ['评分', '进球', '助攻', '关键传球', '抢断'],
datasets: data.map(d => ({
label: d.name,
data: [d.rating * 10, d.goals, d.assists, d.key_passes, d.tackles],
fill: true,
}))
}
});
});
</script>
项目结构建议
whoscored-compare/
├── composer.json
├── config/
│ └── db.php
├── src/
│ ├── Scraper/WhoScoredScraper.php
│ ├── Repository/PlayerRepository.php
│ └── Service/CompareService.php
├── public/
│ ├── index.php
│ └── api/compare.php
├── storage/
│ └── cache/ # 抓取缓存,避免频繁请求
├── cron/
│ └── fetch_ratings.php # 定时抓取
└── views/
└── compare.php
关键注意事项
-
反爬
- 每次请求间隔 ≥ 2 秒
- 失败重试 + 随机 UA
- 数据落库做缓存(评分每日变,抓一次即可)
- 有条件用代理池
-
合规
- 仅做个人学习/分析用途
- 遵守 robots.txt 与 ToS,勿商用
- 高频抓取可能封 IP
-
数据准确性
- 评分口径:WhoScored 的 rating 是 0–10,保留两位小数
- 注意区分赛季、赛事、位置(前锋 vs 后卫评分不可直接比)
- 出场时间门槛(isMinApp=true 排除太少出场)
-
对比维度建议
- 同位置对比才有意义(前锋 vs 前锋)
- 雷达图维度用 同位置分位数 标准化,避免进球数碾压防守数据
后续可扩展
- ⭐ 主客场评分拆分
- ⭐ 时间序列(近 5 场评分趋势)
- ⭐ 同位置分位数排名
- ⭐ 爬虫队列化(Laravel Horizon / Redis)
- ⭐ 导出 Excel / PDF 对比报告
需要我进一步提供具体哪一块的完整可运行代码?
- 带缓存的完整抓取类
- 雷达图标准化对比算法
- Laravel 版本的完整实现
- 反爬绕过方案
告诉我你的项目规模(脚本级 / 小型站 / 完整系统),我给你更贴合的方案。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播