Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Hockey Data Project
#1
Hello! I am currently working on a project relating to retrieving data from the NHL API and have been able to pull from a single team but I can't figure out how to retrieve player data without first retrieving the roster data to get the player id and link. right now I pull an individual team roster based on their API link to get player IDs but I want to be able to query player directly on different teams without possibly having to select the roster first

roster link: http://statsapi.web.nhl.com/api/v1/teams/1/roster
example player link: http://statsapi.web.nhl.com/api/v1/peopl...gleSeason)

import json
from urllib.request import urlopen

url_roster = 'http://statsapi.web.nhl.com/api/v1/teams/1/roster'

Cap_Player_Name = input()
Player_Name = Cap_Player_Name.title()

NHL_url = 'http://statsapi.web.nhl.com'

url_extension = '?hydrate=stats(splits=statsSingleSeason)'

with urlopen(url_roster) as response:
    source = response.read()
    data = json.loads(source)
    for item in data['roster']:
        if item['person']['fullName'] == Player_Name:
            if item['position']['code'] == 'G':
                goalie_code = (item['person']['link'])
                url_full = NHL_url + str(goalie_code) + url_extension
                with urlopen(url_full) as response:
                    source = response.read()
                    data = json.loads(source)
                    for item5 in data['people']:
                        print('')
                        print(item5['fullName'])
                        for item2 in item5['stats']:
                            for item3 in item2['splits']:
                                print('')
                                print('wins: ', item3['stat']['wins'])
                                print('losses: ', item3['stat']['losses'])
                                print('saves: ', item3['stat']['saves'])
                                print('goalAgainstAverage: ', item3['stat']['goalAgainstAverage'], '%')
            elif item['position']['code'] == 'D' or 'C' or 'L' or 'R':
                player_code = (item['person']['link'])
                url_full = NHL_url + str(player_code) + url_extension
                with urlopen(url_full) as response:
                    source = response.read()
                    data = json.loads(source)
                    for item5 in data['people']:
                        print(item5['fullName'])
                        print('')
                        for item2 in item5['stats']:
                            for item3 in item2['splits']:
                                shots = item3['stat']['shots']
                                assists = item3['stat']['assists']
                                goals = item3['stat']['goals']
                                hits = item3['stat']['hits']
                                blocks = item3['stat']['blocked']
                                points = item3['stat']['points']
                                plusMinus = item3['stat']['plusMinus']
                                print('')
                                print('Shots: ', shots)
                                print('Assists: ', assists)
                                print('Goals: ', goals)
                                print('Hits: ', hits)
                                print('Blocks: ', blocks)
                                print('Points: ', points)
                                print('Plus/Minus: ', plusMinus)
Reply
#2
(Mar-24-2020, 05:13 PM)Joeylax54 Wrote: right now I pull an individual team roster based on their API link to get player IDs

Seems sensible. If you don't know the IDs ahead of time, then you have to get them from somewhere and one would assume the /roster endpoint is the natural way to do that.

Quote: but I want to be able to query player directly on different teams without possibly having to select the roster first

Why? What's wrong with making two calls?
Reply
#3
I'm just getting started with Python so bear with me lol, there are currently 32 different roster endpoints (one for each team).

1. First I call the teams to get the Team ID
http://statsapi.web.nhl.com/api/v1/teams

2. Then I call the roster using the specific team ID
http://statsapi.web.nhl.com/api/v1/teams/1/roster

3. Then I can call the player ID from the roster to call player data
http://statsapi.web.nhl.com/api/v1/peopl...gleSeason)

I would like people to call player data via an input on my website of a specific player's name instead of requiring a user to provide the specific team of the player, and then the player name. the only way to obtain a player's team ID is through their personal data in step 3. I guess what I am trying to do is a global search of players rather than by roster.

In the end, I am trying to allow a user to input a player name as an input to a webpage and have that player's stats(data)return.
Reply
#4
If the API doesn't offer a way to search globally, then you'll have to work around that. Did you check the docs already?

In terms of a workaround, what do you think you could do? I have one idea, but perhaps you do too.
Reply
#5
The Web API does not offer its database or documentation such as a CSV file. I have tried all of my workarounds but have come up dry for an answer.
Reply
#6
I'm not sure what you mean with that first sentence. What were the workarounds you thought of?
Reply
#7
Joeylax54 Wrote:I'm just getting started with Python so bear with me lol, there are currently 32 different roster endpoints (one for each team).
Here some hints on a start and use Requests.
So can collect all data bye iterate over all urls.
Then it look like this,try figure name_search function so can search for Ryan Miller and return back 8468011.
import requests

def nhl_all():
    nhl_lst = []
    for team in range(1,31):
        url = f'https://statsapi.web.nhl.com/api/v1/teams/{team}/roster'
        response = requests.get(url)
        json_data = response.json()
        nhl_lst.append(json_data)
    return nhl_lst

def name_search(json_data, name):
    pass

if __name__ == '__main__':
    json_data = nhl_all()
    print(json_data)
    #name = 'Ryan Miller'
    #print(name_search(json_data, name)) # 8468011

    ''' Test data
    name = 'Ryan Miller'
    # https://statsapi.web.nhl.com/api/v1/teams/24/roster
    # 8468011
    '''
Reply
#8
I found the simple solution to find players from different teams
NHL_url = 'http://statsapi.web.nhl.com'

url_extension = '?hydrate=stats(splits=statsSingleSeason)'
url_teams = 'https://statsapi.web.nhl.com/api/v1/teams'
url_teams2 = 'https://statsapi.web.nhl.com/api/v1/teams/'
url_roster_extension = '/roster'

with urlopen(url_teams) as response:
    source = response.read()
    data = json.loads(source)
    for teams in data['teams']:
        team_id2 = teams['id']
        url_full2 = url_teams2 + str(team_id2) + url_roster_extension
        url_roster = url_full2
        with urlopen(url_roster) as response:
            source = response.read()
            data = json.loads(source)
            for item in data['roster']:
                if item['person']['fullName'] == Player_Name:
                    if item['position']['code'] == 'G':
                        goalie_code = (item['person']['link'])
                        url_full = NHL_url + str(goalie_code) + url_extension
                        with urlopen(url_full) as response:
                            source = response.read()
                            data = json.loads(source)
                            for item5 in data['people']:
                                print('')
                                print(item5['fullName'])
                                for item2 in item5['stats']:
                                    for item3 in item2['splits']:
                                        wins = item3['stat']['wins']
                                        losses = item3['stat']['losses']
                                        goalsAgainst = item3['stat']['goalsAgainst']
                                        shotsAgainst = item3['stat']['shotsAgainst']
                                        evenSaves = item3['stat']['evenSaves']
                                        savePercentage = item3['stat']['savePercentage']
                                        goalagainstaverage = item3['stat']['goalAgainstAverage']
                                        print('')
                                        print('Wins: ', wins)
                                        print('Losses: ', losses)
                                        print('GA: ', goalsAgainst)
                                        print('SA: ', shotsAgainst)
                                        print('SV: ', evenSaves)
                                        print('SV%: ', savePercentage, '%')
                                        print('GAA: ', goalagainstaverage, )
Reply
#9
if you know the player's name, you can use the following API: https://suggest.svc.nhl.com/svc/suggest/...veplayers/{player_name_goes_here}/99999

that's the REST call used on the NHL's player search page (https://www.nhl.com/player)

it returns an array of "suggestions"; so using https://suggest.svc.nhl.com/svc/suggest/...arls/99999 returns the following:
{
"suggestions": [
"8474590|Carlson|John|1|0|6' 3\"|217|Natick|MA|USA|1990-01-10|WSH|D|74|john-carlson-8474590",
"8478506|Carlsson|Gabriel|1|1|6' 5\"|192|Orebro||SWE|1997-01-02|CBJ|D|53|gabriel-carlsson-8478506",
"8479523|Carlsson|Lucas|1|1|6' 0\"|189|Gävle||SWE|1997-07-05|CHI|D|46|lucas-carlsson-8479523"
]
}

what's the "99999" at the end of the url for? that's the max count of items to return; i usually just leave it huge so as not to lose any results.

if you have the full name, it should return just the single match in the results (i.e. an array of 1). then just parse the pipe-delimited text to get the player's ID and you should be able to pop that into your player REST call and you're good to go.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020