Created
November 27, 2025 23:50
-
-
Save Ascor8522/2e14c05654ca1c58ff8e1877f04b7dca to your computer and use it in GitHub Desktop.
Script to download goalie statistics from hockeylinea.fmp.es for a given league and save them into an Excel workbook, with one worksheet per game.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # hockey.ps1 | |
| # | |
| # DESCRIPTION: | |
| # ============ | |
| # Script to download goalie statistics from hockeylinea.fmp.es for a given league | |
| # and save them into an Excel workbook, with one worksheet per game. | |
| # | |
| # COPYRIGHT AND LICENSE: | |
| # ====================== | |
| # Copyright (c) 2025 Ascor8522 | |
| # Licensed under the MIT License | |
| # | |
| # REQUIREMENTS: | |
| # ============= | |
| # - PowerShell 7+ | |
| # - Excel installed on the machine running the script | |
| $lang = "es" | |
| $idc = "4169" # <---- League ID (4169 for "LIGA SENIOR 3 GRUPO A 2025/26") | |
| $idm = "2" | |
| Function Fetch-Games($Idc, $Idm) { | |
| $url = "https://www.server2.sidgad.es/fmp/fmp_cal_idc_${Idc}_${Idm}.php" | |
| $regex = '<i class="fa fa-search game_report" idp="(?<idp>\d+?)" idc="(?<idc>\d+?)" idm="(?<idm>\d+?)"' | |
| return Invoke-WebRequest -Uri $url ` | |
| -Method POST ` | |
| -Headers @{ Origin = "http://www.hockeylinea.fmp.es" } ` | |
| -Body @{ idc = $Idc; site_lang = $lang } | |
| | Select-Object -ExpandProperty Content | |
| | % { [regex]::Matches($_, $regex) } | |
| | ForEach-Object { | |
| [PSCustomObject]@{ | |
| idp = $_.Groups['idp'].Value | |
| idc = $_.Groups['idc'].Value | |
| idm = $_.Groups['idm'].Value | |
| } | |
| } | |
| } | |
| Function Fetch-GameDetails($Idp, $Idm, $Idc) { | |
| $url = "https://www.server2.sidgad.es/fmp/fmp_gr_${Idp}_${Idm}.php" | |
| $tablesRegex = '<table width="100%" class="competiciones_tabla_basic"(?:.|\n)+?<\/table>' | |
| $teams = Invoke-WebRequest -Uri $url ` | |
| -Method POST ` | |
| -Headers @{ Origin = "http://www.hockeylinea.fmp.es" } ` | |
| -Body @{ idm = $Idm; idc = $Idc; idp = $Idp; tab = "tab_ficha_resumen"; site_lang = $lang } ` | |
| | Select-Object -ExpandProperty Content | |
| | % { [regex]::Matches($_, $tablesRegex) } | |
| | % { $_.Value } | |
| | ForEach-Object { | |
| $fixRegex = [regex]'(?<=<th>\s*(?:<span class="lang_label lang_..">.+?<\/span>\s*)+)(?=\s*<th>)' | |
| $fixed = $_ | |
| | % { $_ -replace '<img(.*?)\/?>', '<img$1></img>' } | |
| | % { $fixRegex.replace($_, '</th>', 1) } | |
| $xml = $fixed | |
| | % { [xml]($_) } | |
| $nameXpath = '//table/thead/tr/td/div[@class="nombre_equipo_thickbox_stats"]' | |
| $teamName = $xml.SelectNodes($nameXpath) | ForEach-Object { $_.'#text' } | |
| $goaliesXpath = '//table/tbody/tr[preceding-sibling::thead[1] = //table/tbody/thead[1]]' | |
| $goalies = $xml.SelectNodes($goaliesXpath) | ForEach-Object { | |
| [PSCustomObject]@{ | |
| Number = $_.td[0].'#text' | Select-Object -First 1 | % { $_.Trim() } | |
| Position = $_.td[1].'#text' | Select-Object -First 1 | % { $_.Trim() } | |
| Flag = $_.td[2].img.'@src' | Select-Object -First 1 | % { $_.Trim() } | |
| LastName = $_.td[3].a.'#text' | Select-Object -First 1 | % { $_.Trim() } | |
| FirstName = $_.td[3].a.span.'#text' | Select-Object -First 1 | % { $_.Trim() } | |
| GA = $_.td[4].'#text' | Select-Object -First 1 | % { $_.Trim() } | |
| TR = $_.td[5].'#text' | Select-Object -First 1 | % { $_.Trim() } | |
| Pct = $_.td[6].'#text' | Select-Object -First 1 | % { $_.Trim() } | |
| PIM = $_.td[7].'#text' | Select-Object -First 1 | % { $_.Trim() } | |
| Min = $_.td[8].'#text' | Select-Object -First 1 | % { $_.Trim() } | |
| Pm = $_.td[9].'#text' | Select-Object -First 1 | % { $_.Trim() } | |
| } | |
| } | |
| [PSCustomObject]@{ | |
| TeamName = $teamName | |
| Goalies = $goalies | |
| } | |
| } | |
| [PSCustomObject]@{ | |
| Idp = $Idp | |
| Idm = $Idm | |
| Idc = $Idc | |
| Teams = $teams | |
| } | |
| } | |
| Function Insert-MatchInWorkbook($Workbook, $Game) { | |
| $ws = $Workbook.Worksheets.Add([System.Type]::Missing, $Workbook.Worksheets[$Workbook.Worksheets.Count], 1, -4167) | |
| $ws.Name = "Game_$($Game.Idp)_$($Game.Teams[0].TeamName -replace '\s','_')_vs_$($Game.Teams[1].TeamName -replace '\s','_')" | |
| | % { $_.Substring(0, [Math]::Min(31, $_.Length)) } | |
| $row = 1 | |
| $Game.Teams | ForEach-Object { | |
| $ws.Cells.Item($row, 1).Value2 = $_.TeamName -join ' ' | |
| $row++ | |
| $col = 1 | |
| $headers = @("N°", "Pos.", "Flag", "Last Name", "First Name", "GA", "TR", "%", "PIM", "Min", "+/-") | |
| $widths = @(20, 5, 5, 20, 15, 5, 5, 8, 5, 5, 5) | |
| $headers | ForEach-Object { | |
| $ws.Cells.Item($row, $col).Value2 = $_ | |
| $ws.Columns.Item($col).ColumnWidth = $widths[$col - 1] | |
| $col++ | |
| } | |
| $row++ | |
| $_.Goalies | ForEach-Object { | |
| $ws.Cells.Item($row, 1).Value2 = $_.Number | |
| $ws.Cells.Item($row, 2).Value2 = $_.Position | |
| $ws.Cells.Item($row, 3).Value2 = $_.Flag | |
| $ws.Cells.Item($row, 4).Value2 = $_.LastName | |
| $ws.Cells.Item($row, 5).Value2 = $_.FirstName | |
| $ws.Cells.Item($row, 6).Value2 = $_.GA | |
| $ws.Cells.Item($row, 7).Value2 = $_.TR | |
| $ws.Cells.Item($row, 8).Value2 = $_.Pct | |
| $ws.Cells.Item($row, 9).Value2 = $_.PIM | |
| $ws.Cells.Item($row, 10).Value2 = $_.Min | |
| $ws.Cells.Item($row, 11).Value2 = $_.Pm | |
| $row++ | |
| } | |
| } | |
| [System.Runtime.Interopservices.Marshal]::ReleaseComObject($ws) | Out-Null | |
| } | |
| Function Main() { | |
| $ErrorActionPreference = "Stop" | |
| $PSNativeCommandUseErrorActionPreference = $true | |
| $xl = New-Object -ComObject Excel.Application | |
| $wb = $xl.Workbooks.Add() | |
| $games = Fetch-Games $idc $idm | |
| foreach ($game in $games) { | |
| $gameDetails = Fetch-GameDetails $game.idp $game.idm $game.idc | |
| Insert-MatchInWorkbook $wb $gameDetails | |
| } | |
| $wb.Worksheets.Item(1).Delete() | |
| $wb.Worksheets.Item(1).Activate() | |
| $savePath = ".\goalie_stats_of_league_$idc`_on_$((Get-Date).ToString("yyyy-MM-dd-a\t_HH-mm-ss")).xlsx" | |
| '' | Out-File $savePath | |
| $xl.DisplayAlerts = $false | |
| $wb.SaveAs((Resolve-Path $savePath).Path) | |
| $wb.Close() | |
| [System.Runtime.Interopservices.Marshal]::ReleaseComObject($wb) | Out-Null | |
| $xl.Quit() | |
| [System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl) | Out-Null | |
| [GC]::Collect() | |
| [GC]::WaitForPendingFinalizers() | |
| } | |
| Main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment