refactor: consolidate data/ into single root directory, fix historical player names

Merge data/wikipedia/{year}/ into data/{year}/ so there is a single
canonical location for World Cup JSON files. Update scrape and seed
scripts to use data/ instead of data/wikipedia/.

Re-scraped all 22 years (1930-2022) with fixed player name extraction
(full name from <a title="..."> rather than abbreviated display text)
so historical goals now show e.g. "Thomas Müller" not "Müller".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-15 18:27:35 +02:00
parent 9ce2a4e27c
commit d37ebe201e
48 changed files with 2488 additions and 3630 deletions
+107 -288
View File
@@ -14,7 +14,7 @@
},
"goals1": [
{
"name": "Neuville",
"name": "Oliver Neuville",
"minute": 88
}
],
@@ -34,15 +34,15 @@
},
"goals2": [
{
"name": "Ferdinand",
"name": "Rio Ferdinand",
"minute": 5
},
{
"name": "Owen",
"name": "Michael Owen",
"minute": 22
},
{
"name": "Heskey",
"name": "Emile Heskey",
"minute": 44
}
],
@@ -66,13 +66,13 @@
},
"goals1": [
{
"name": "Larsson",
"name": "Henrik Larsson",
"minute": 11
}
],
"goals2": [
{
"name": "Camara",
"name": "Henri Camara",
"minute": 37
}
],
@@ -100,7 +100,7 @@
},
"goals1": [
{
"name": "Morientes",
"name": "Fernando Morientes",
"minute": 8
}
],
@@ -127,11 +127,11 @@
},
"goals2": [
{
"name": "McBride",
"name": "Brian McBride",
"minute": 8
},
{
"name": "Donovan",
"name": "Landon Donovan",
"minute": 65
}
],
@@ -175,7 +175,7 @@
},
"goals2": [
{
"name": "Davala",
"name": "Ümit Davala",
"minute": 12
}
],
@@ -205,7 +205,7 @@
],
"goals2": [
{
"name": "Vieri",
"name": "Christian Vieri",
"minute": 18
}
],
@@ -225,7 +225,7 @@
},
"goals1": [
{
"name": "Owen",
"name": "Michael Owen",
"minute": 23
}
],
@@ -256,7 +256,7 @@
},
"goals1": [
{
"name": "Ballack",
"name": "Michael Ballack",
"minute": 39
}
],
@@ -316,7 +316,7 @@
},
"goals1": [
{
"name": "Ballack",
"name": "Michael Ballack",
"minute": 75
}
],
@@ -367,15 +367,15 @@
],
"goals2": [
{
"name": "Şükür",
"name": "Hakan Şükür",
"minute": 1
},
{
"name": "Mansız",
"name": "İlhan Mansız",
"minute": 13
},
{
"name": "Mansız",
"name": "İlhan Mansız",
"minute": 32
}
],
@@ -420,7 +420,7 @@
},
"goals2": [
{
"name": "Bouba Diop",
"name": "Papa Bouba Diop",
"minute": 30
}
],
@@ -441,17 +441,17 @@
},
"goals1": [
{
"name": "Rodríguez",
"name": "Darío Rodríguez",
"minute": 47
}
],
"goals2": [
{
"name": "Tomasson",
"name": "Jon Dahl Tomasson",
"minute": 45
},
{
"name": "Tomasson",
"name": "Jon Dahl Tomasson",
"minute": 83
}
],
@@ -472,14 +472,14 @@
},
"goals1": [
{
"name": "Tomasson",
"name": "Jon Dahl Tomasson",
"minute": 16,
"penalty": true
}
],
"goals2": [
{
"name": "Diao",
"name": "Salif Diao",
"minute": 52
}
],
@@ -515,11 +515,11 @@
},
"goals1": [
{
"name": "Rommedahl",
"name": "Dennis Rommedahl",
"minute": 22
},
{
"name": "Tomasson",
"name": "Jon Dahl Tomasson",
"minute": 67
}
],
@@ -540,30 +540,30 @@
},
"goals1": [
{
"name": "Fadiga",
"name": "Khalilou Fadiga",
"minute": 20,
"penalty": true
},
{
"name": "Bouba Diop",
"name": "Papa Bouba Diop",
"minute": 26
},
{
"name": "Bouba Diop",
"name": "Papa Bouba Diop",
"minute": 38
}
],
"goals2": [
{
"name": "Morales",
"name": "Richard Morales",
"minute": 46
},
{
"name": "Forlán",
"name": "Diego Forlán",
"minute": 69
},
{
"name": "Recoba",
"name": "Álvaro Recoba",
"minute": 88,
"penalty": true
}
@@ -585,21 +585,21 @@
},
"goals1": [
{
"name": "Santa Cruz",
"name": "Roque Santa Cruz",
"minute": 39
},
{
"name": "Arce",
"name": "Francisco Arce",
"minute": 55
}
],
"goals2": [
{
"name": "T. Mokoena",
"name": "Teboho Mokoena",
"minute": 63
},
{
"name": "Fortune",
"name": "Quinton Fortune",
"minute": 90,
"offset": 1,
"penalty": true
@@ -626,18 +626,18 @@
"minute": 44
},
{
"name": "Valerón",
"name": "Juan Carlos Valerón",
"minute": 74
},
{
"name": "Hierro",
"name": "Fernando Hierro",
"minute": 87,
"penalty": true
}
],
"goals2": [
{
"name": "Cimirotič",
"name": "Sebastjan Cimirotič",
"minute": 82
}
],
@@ -658,22 +658,22 @@
},
"goals1": [
{
"name": "Morientes",
"name": "Fernando Morientes",
"minute": 53
},
{
"name": "Morientes",
"name": "Fernando Morientes",
"minute": 69
},
{
"name": "Hierro",
"name": "Fernando Hierro",
"minute": 83,
"penalty": true
}
],
"goals2": [
{
"name": "Puyol",
"name": "Carles Puyol",
"minute": 10,
"owngoal": true
}
@@ -695,7 +695,7 @@
},
"goals1": [
{
"name": "Nomvethe",
"name": "Siyabonga Nomvethe",
"minute": 4
}
],
@@ -716,11 +716,11 @@
},
"goals1": [
{
"name": "McCarthy",
"name": "Benni McCarthy",
"minute": 31
},
{
"name": "Radebe",
"name": "Lucas Radebe",
"minute": 53
}
],
@@ -734,7 +734,7 @@
"minute": 56
},
{
"name": "Mendieta",
"name": "Gaizka Mendieta",
"minute": 45,
"offset": 1
}
@@ -756,22 +756,22 @@
},
"goals1": [
{
"name": "Ačimovič",
"name": "Milenko Ačimovič",
"minute": 45,
"offset": 1
}
],
"goals2": [
{
"name": "Cuevas",
"name": "Nelson Cuevas",
"minute": 65
},
{
"name": "Cuevas",
"name": "Nelson Cuevas",
"minute": 84
},
{
"name": "Campos",
"name": "Jorge Luis Campos",
"minute": 73
}
],
@@ -803,7 +803,7 @@
],
"goals2": [
{
"name": "Şaş",
"name": "Hasan Şaş",
"minute": 45,
"offset": 2
}
@@ -825,11 +825,11 @@
},
"goals2": [
{
"name": "Gómez",
"name": "Rónald Gómez",
"minute": 61
},
{
"name": "Wright",
"name": "Mauricio Wright",
"minute": 65
}
],
@@ -884,13 +884,13 @@
},
"goals1": [
{
"name": "Parks",
"name": "Winston Parks",
"minute": 86
}
],
"goals2": [
{
"name": "Belözoğlu",
"name": "Emre Belözoğlu",
"minute": 56
}
],
@@ -911,11 +911,11 @@
},
"goals1": [
{
"name": "Wanchope",
"name": "Paulo Wanchope",
"minute": 39
},
{
"name": "Gómez",
"name": "Rónald Gómez",
"minute": 56
}
],
@@ -937,7 +937,7 @@
"minute": 62
},
{
"name": "Júnior",
"name": "Jenílson Ângelo de Souza",
"minute": 64
}
],
@@ -958,15 +958,15 @@
},
"goals1": [
{
"name": "Şaş",
"name": "Hasan Şaş",
"minute": 6
},
{
"name": "Korkmaz",
"name": "Bülent Korkmaz",
"minute": 9
},
{
"name": "Davala",
"name": "Ümit Davala",
"minute": 85
}
],
@@ -1012,16 +1012,16 @@
},
"goals1": [
{
"name": "O'Brien",
"name": "John O'Brien",
"minute": 4
},
{
"name": "J. Costa",
"name": "Jorge Costa",
"minute": 29,
"owngoal": true
},
{
"name": "McBride",
"name": "Brian McBride",
"minute": 36
}
],
@@ -1031,7 +1031,7 @@
"minute": 39
},
{
"name": "Agoos",
"name": "Jeff Agoos",
"minute": 71,
"owngoal": true
}
@@ -1059,7 +1059,7 @@
],
"goals2": [
{
"name": "Mathis",
"name": "Clint Mathis",
"minute": 24
}
],
@@ -1134,207 +1134,26 @@
},
"goals1": [
{
"name": "Olisadebe",
"name": "Emmanuel Olisadebe",
"minute": 3
},
{
"name": "Kryszałowicz",
"name": "Paweł Kryszałowicz",
"minute": 5
},
{
"name": "Żewłakow",
"name": "Marcin Żewłakow",
"minute": 66
}
],
"goals2": [
{
"name": "Donovan",
"name": "Landon Donovan",
"minute": 83
}
],
"ground": "Daejeon World Cup Stadium, Daejeon"
},
{
"round": "Group stage",
"group": "Group E",
"date": "2002-06-01",
"time": "15:30",
"team1": "Republic of Ireland",
"team2": "Cameroon",
"score": {
"ft": [
1,
1
]
},
"goals1": [
{
"name": "Holland",
"minute": 52
}
],
"goals2": [
{
"name": "M'Boma",
"minute": 39
}
],
"ground": "Niigata Stadium, Niigata"
},
{
"round": "Group stage",
"group": "Group E",
"date": "2002-06-01",
"time": "20:30",
"team1": "Germany",
"team2": "Saudi Arabia",
"score": {
"ft": [
8,
0
]
},
"goals1": [
{
"name": "Klose",
"minute": 20
},
{
"name": "Klose",
"minute": 25
},
{
"name": "Klose",
"minute": 70
},
{
"name": "Ballack",
"minute": 40
},
{
"name": "Jancker",
"minute": 45,
"offset": 1
},
{
"name": "Linke",
"minute": 73
},
{
"name": "Bierhoff",
"minute": 84
},
{
"name": "Schneider",
"minute": 90,
"offset": 1
}
],
"ground": "Sapporo Dome, Sapporo"
},
{
"round": "Group stage",
"group": "Group E",
"date": "2002-06-05",
"time": "20:30",
"team1": "Germany",
"team2": "Republic of Ireland",
"score": {
"ft": [
1,
1
]
},
"goals1": [
{
"name": "Klose",
"minute": 19
}
],
"goals2": [
{
"name": "Robbie Keane",
"minute": 90,
"offset": 2
}
],
"ground": "Kashima Soccer Stadium, Ibaraki"
},
{
"round": "Group stage",
"group": "Group E",
"date": "2002-06-06",
"time": "18:00",
"team1": "Cameroon",
"team2": "Saudi Arabia",
"score": {
"ft": [
1,
0
]
},
"goals1": [
{
"name": "Eto'o",
"minute": 66
}
],
"ground": "Saitama Stadium, Saitama"
},
{
"round": "Group stage",
"group": "Group E",
"date": "2002-06-11",
"time": "20:30",
"team1": "Cameroon",
"team2": "Germany",
"score": {
"ft": [
0,
2
]
},
"goals2": [
{
"name": "Bode",
"minute": 50
},
{
"name": "Klose",
"minute": 79
}
],
"ground": "Ecopa Stadium, Shizuoka"
},
{
"round": "Group stage",
"group": "Group E",
"date": "2002-06-11",
"time": "20:30",
"team1": "Saudi Arabia",
"team2": "Republic of Ireland",
"score": {
"ft": [
0,
3
]
},
"goals2": [
{
"name": "Robbie Keane",
"minute": 7
},
{
"name": "Breen",
"minute": 61
},
{
"name": "Duff",
"minute": 87
}
],
"ground": "International Stadium Yokohama, Yokohama"
},
{
"round": "Group stage",
"group": "Group F",
@@ -1350,7 +1169,7 @@
},
"goals1": [
{
"name": "Batistuta",
"name": "Gabriel Batistuta",
"minute": 63
}
],
@@ -1371,13 +1190,13 @@
},
"goals1": [
{
"name": "Campbell",
"name": "Sol Campbell",
"minute": 24
}
],
"goals2": [
{
"name": "Alexandersson",
"name": "Niclas Alexandersson",
"minute": 59
}
],
@@ -1398,18 +1217,18 @@
},
"goals1": [
{
"name": "Larsson",
"name": "Henrik Larsson",
"minute": 35
},
{
"name": "Larsson",
"name": "Henrik Larsson",
"minute": 63,
"penalty": true
}
],
"goals2": [
{
"name": "Aghahowa",
"name": "Julius Aghahowa",
"minute": 27
}
],
@@ -1430,7 +1249,7 @@
},
"goals2": [
{
"name": "Beckham",
"name": "David Beckham",
"minute": 44,
"penalty": true
}
@@ -1452,13 +1271,13 @@
},
"goals1": [
{
"name": "A. Svensson",
"name": "Anders Svensson",
"minute": 59
}
],
"goals2": [
{
"name": "Crespo",
"name": "Hernán Crespo",
"minute": 88
}
],
@@ -1494,7 +1313,7 @@
},
"goals2": [
{
"name": "Blanco",
"name": "Cuauhtémoc Blanco",
"minute": 60,
"penalty": true
}
@@ -1516,11 +1335,11 @@
},
"goals1": [
{
"name": "Vieri",
"name": "Christian Vieri",
"minute": 7
},
{
"name": "Vieri",
"name": "Christian Vieri",
"minute": 27
}
],
@@ -1541,17 +1360,17 @@
},
"goals1": [
{
"name": "Vieri",
"name": "Christian Vieri",
"minute": 55
}
],
"goals2": [
{
"name": "Olić",
"name": "Ivica Olić",
"minute": 73
},
{
"name": "Rapaić",
"name": "Milan Rapaić",
"minute": 76
}
],
@@ -1572,17 +1391,17 @@
},
"goals1": [
{
"name": "Borgetti",
"name": "Jared Borgetti",
"minute": 28
},
{
"name": "Torrado",
"name": "Gerardo Torrado",
"minute": 57
}
],
"goals2": [
{
"name": "Delgado",
"name": "Agustín Delgado",
"minute": 5
}
],
@@ -1603,13 +1422,13 @@
},
"goals1": [
{
"name": "Borgetti",
"name": "Jared Borgetti",
"minute": 34
}
],
"goals2": [
{
"name": "Del Piero",
"name": "Alessandro Del Piero",
"minute": 85
}
],
@@ -1630,7 +1449,7 @@
},
"goals1": [
{
"name": "Méndez",
"name": "Édison Méndez",
"minute": 48
}
],
@@ -1651,21 +1470,21 @@
},
"goals1": [
{
"name": "Suzuki",
"name": "Takayuki Suzuki",
"minute": 59
},
{
"name": "Inamoto",
"name": "Junichi Inamoto",
"minute": 67
}
],
"goals2": [
{
"name": "Wilmots",
"name": "Marc Wilmots",
"minute": 57
},
{
"name": "Van der Heyden",
"name": "Peter Van der Heyden",
"minute": 75
}
],
@@ -1686,11 +1505,11 @@
},
"goals1": [
{
"name": "Titov",
"name": "Yegor Titov",
"minute": 59
},
{
"name": "Karpin",
"name": "Valery Karpin",
"minute": 64,
"penalty": true
}
@@ -1712,7 +1531,7 @@
},
"goals1": [
{
"name": "Inamoto",
"name": "Junichi Inamoto",
"minute": 51
}
],
@@ -1733,13 +1552,13 @@
},
"goals1": [
{
"name": "Bouzaiene",
"name": "Raouf Bouzaiene",
"minute": 17
}
],
"goals2": [
{
"name": "Wilmots",
"name": "Marc Wilmots",
"minute": 13
}
],
@@ -1760,11 +1579,11 @@
},
"goals2": [
{
"name": "Morishima",
"name": "Hiroaki Morishima",
"minute": 48
},
{
"name": "H. Nakata",
"name": "Hidetoshi Nakata",
"minute": 75
}
],
@@ -1785,25 +1604,25 @@
},
"goals1": [
{
"name": "Walem",
"name": "Johan Walem",
"minute": 7
},
{
"name": "Sonck",
"name": "Wesley Sonck",
"minute": 78
},
{
"name": "Wilmots",
"name": "Marc Wilmots",
"minute": 82
}
],
"goals2": [
{
"name": "Beschastnykh",
"name": "Vladimir Beschastnykh",
"minute": 52
},
{
"name": "Sychev",
"name": "Dmitri Sychev",
"minute": 88
}
],