Repository: mjk2244/pro-football-reference-web-scraper (language: python)

Issue:
configuration edits



Discussion / hints:

Fix patch:
diff --git a/MANIFEST.in b/MANIFEST.in
index 4926a30..064f2ce 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,4 @@
-graft example_project_python
+graft pro-football-reference-web-scraper
 
 include LICENSE
 include README.md
@@ -21,4 +21,4 @@ global-exclude *.pyc
 global-exclude *.pyo
 global-exclude .git
 global-exclude .ipynb_checkpoints
-global-exclude .DS_Store
+global-exclude .DS_Store
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 7275c61..c2ae76a 100644
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,7 @@ lints: lint
 
 format:  ## run autoformatting with black
 	python -m black setup.py
-	python -m black src/player_game_log.py
+	python -m black src
 	python -m black tests
 
 # alias
diff --git a/pyproject.toml b/pyproject.toml
index 20cadc2..94e8ef3 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -16,7 +16,8 @@ requires-python = ">=3.7"
 
 dependencies = ["beautifulsoup4>=4.9.0",
                 "requests>=2.28.2",
-                "pandas>=1.5.3"]
+                "pandas>=1.5.3",
+                "haversine>=2.4.0"]
 
 classifiers = [
     "Development Status :: 2 - Pre-Alpha",
diff --git a/src/team_game_log.py b/src/team_game_log.py
new file mode 100644
index 0000000..7932dcf
--- /dev/null
+++ b/src/team_game_log.py
@@ -0,0 +1,291 @@
+from bs4 import BeautifulSoup
+import requests
+import pandas as pd
+from datetime import date
+from haversine import haversine, Unit
+
+# TODO: add older teams to this list
+team_hrefs = {
+    'Arizona Cardinals': 'crd',
+    'Baltimore Colts': 'clt',
+    'St. Louis Cardinals': 'crd',
+    'Boston Patriots': 'nwe',
+    'Chicago Bears': 'chi',
+    'Green Bay Packers': 'gnb',
+    'New York Giants': 'nyg',
+    'Detroit Lions': 'det',
+    'Washington Commanders': 'was',
+    'Washington Football Team': 'was',
+    'Washington Redskins': 'was',
+    'Philadelphia Eagles': 'phi',
+    'Pittsburgh Steelers': 'pit',
+    'Los Angeles Chargers': 'sdg',
+    'San Francisco 49ers': 'sfo',
+    'Houston Oilers': 'oti',
+    'Cleveland Browns': 'cle',
+    'Indianapolis Colts': 'clt',
+    'Dallas Cowboys': 'dal',
+    'Kansas City Chiefs': 'kan',
+    'Los Angeles Rams': 'ram',
+    'Denver Broncos': 'den',
+    'New York Jets': 'nyj',
+    'New England Patriots': 'nwe',
+    'Las Vegas Raiders': 'rai',
+    'Tennessee Titans': 'oti',
+    'Tennessee Oilers': 'oti',
+    'Phoenix Cardinals': 'crd',
+    'Los Angeles Raiders': 'rai',
+    'Buffalo Bills': 'buf',
+    'Minnesota Vikings': 'min',
+    'Atlanta Falcons': 'atl',
+    'Miami Dolphins': 'mia',
+    'New Orleans Saints': 'nor',
+    'Cincinnati Bengals': 'cin',
+    'Seattle Seahawks': 'sea',
+    'Tampa Bay Buccaneers': 'tam',
+    'Carolina Panthers': 'car',
+    'Jacksonville Jaguars': 'jax',
+    'Baltimore Ravens': 'rav',
+    'Houston Texans': 'htx',
+    'Oakland Raiders': 'rai',
+    'San Diego Chargers': 'sdg',
+    'St. Louis Rams': 'ram',
+}
+
+months = {"September": 9, "October": 10, "November": 11, "December": 12, "January": 1}
+
+locations = {
+    'Phoenix': {'latitude': 33.4352, 'longitude': 112.0101, 'airport': 'PHX'},
+    'Chicago': {'latitude': 41.9803, 'longitude': 87.9090, 'airport': 'ORD'},
+    'Green Bay': {'latitude': 44.4923, 'longitude': 88.1278, 'airport': 'GRB'},
+    'New York': {'latitude': 40.6895, 'longitude': 74.1745, 'airport': 'EWR'},
+    'Detroit': {'latitude': 42.2162, 'longitude': 83.3554, 'airport': 'DTW'},
+    'Washington DC': {'latitude': 38.9531, 'longitude': 77.4565, 'airport': 'IAD'},
+    'Philadelphia': {'latitude': 39.9526, 'longitude': 75.1652, 'airport': 'PHL'},
+    'Pittsburgh': {'latitude': 40.4919, 'longitude': 80.2352, 'airport': 'PIT'},
+    'Los Angeles': {'latitude': 33.9416, 'longitude': 118.4085, 'airport': 'LAX'},
+    'San Francisco': {'latitude': 37.3639, 'longitude': 121.9289, 'airport': 'SJC'},
+    'Cleveland': {'latitude': 41.4058, 'longitude': 81.8539, 'airport': 'CLE'},
+    'Indianapolis': {'latitude': 39.7169, 'longitude': 86.2956, 'airport': 'IND'},
+    'Dallas': {'latitude': 32.8998, 'longitude': 97.0403, 'airport': 'DFW'},
+    'Kansas City': {'latitude': 39.3036, 'longitude': 94.7093, 'airport': 'MCI'},
+    'Denver': {'latitude': 39.8564, 'longitude': 104.6764, 'airport': 'DEN'},
+    'Providence': {'latitude': 41.7235, 'longitude': 71.4270, 'airport': 'PVD'},
+    'Las Vegas': {'latitude': 36.0840, 'longitude': 115.1537, 'airport': 'LAS'},
+    'Nashville': {'latitude': 36.1263, 'longitude': 86.6774, 'airport': 'BNA'},
+    'Buffalo': {'latitude': 42.9397, 'longitude': 78.7295, 'airport': 'BUF'},
+    'Minneapolis': {'latitude': 44.8848, 'longitude': 93.2223, 'airport': 'MSP'},
+    'Atlanta': {'latitude': 33.6407, 'longitude': 84.4277, 'airport': 'ATL'},
+    'Miami': {'latitude': 26.0742, 'longitude': 80.1506, 'airport': 'FLL'},
+    'New Orleans': {'latitude': 29.9911, 'longitude': 90.2592, 'airport': 'MSY'},
+    'Cincinnati': {'latitude': 39.0508, 'longitude': 84.6673, 'airport': 'CVG'},
+    'Seattle': {'latitude': 47.4480, 'longitude': 122.3088, 'airport': 'SEA'},
+    'Tampa Bay': {'latitude': 27.9772, 'longitude': 82.5311, 'airport': 'TPA'},
+    'Charlotte': {'latitude': 35.2144, 'longitude': 80.9473, 'airport': 'CLT'},
+    'Jacksonville': {'latitude': 30.4941, 'longitude': 81.6879, 'airport': 'JAX'},
+    'Baltimore': {'latitude': 39.1774, 'longitude': 76.6684, 'airport': 'BWI'},
+    'Houston': {'latitude': 29.9902, 'longitude': 95.3368, 'airport': 'IAH'},
+    'Oakland': {'latitude': 37.7126, 'longitude': 122.2197, 'airport': 'OAK'},
+    'San Diego': {'latitude': 32.7338, 'longitude': 117.1933, 'airport': 'SAN'},
+    'St. Louis': {'latitude': 38.7499, 'longitude': 90.3748, 'airport': 'STL'},
+}
+
+cities = {
+    'Arizona Cardinals': 'Phoenix',
+    'Chicago Bears': 'Chicago',
+    'Green Bay Packers': 'Green Bay',
+    'New York Giants': 'New York',
+    'Detroit Lions': 'Detroit',
+    'Washington Commanders': 'Washington DC',
+    'Washington Football Team': 'Washington DC',
+    'Washington Redskins': 'Washington DC',
+    'Philadelphia Eagles': 'Philadelphia',
+    'Pittsburgh Steelers': 'Pittsburgh',
+    'Los Angeles Chargers': 'Los Angeles',
+    'San Francisco 49ers': 'San Francisco',
+    'Houston Oilers': 'Houston',
+    'Cleveland Browns': 'Cleveland',
+    'Indianapolis Colts': 'Indianapolis',
+    'Dallas Cowboys': 'Dallas',
+    'Kansas City Chiefs': 'Kansas City',
+    'Los Angeles Rams': 'Los Angeles',
+    'Denver Broncos': 'Denver',
+    'New York Jets': 'New York',
+    'New England Patriots': 'Providence',
+    'Las Vegas Raiders': 'Las Vegas',
+    'Tennessee Titans': 'Nashville',
+    'Tennessee Oilers': 'Nashville',
+    'Phoenix Cardinals': 'Phoenix',
+    'Los Angeles Raiders': 'Los Angeles',
+    'Buffalo Bills': 'Buffalo',
+    'Minnesota Vikings': 'Minneapolis',
+    'Atlanta Falcons': 'Atlanta',
+    'Miami Dolphins': 'Miami',
+    'New Orleans Saints': 'New Orleans',
+    'Cincinnati Bengals': 'Cincinnati',
+    'Seattle Seahawks': 'Seattle',
+    'Tampa Bay Buccaneers': 'Tampa Bay',
+    'Carolina Panthers': 'Charlotte',
+    'Jacksonville Jaguars': 'Jacksonville',
+    'Baltimore Ravens': 'Baltimore',
+    'Houston Texans': 'Houston',
+    'Oakland Raiders': 'Oakland',
+    'San Diego Chargers': 'San Diego',
+    'St. Louis Rams': 'St. Louis',
+    'Baltimore Colts': 'Baltimore',
+    'St. Louis Cardinals': 'St. Louis',
+    # 'Boston Patriots': 'Boston' add Boston to locations dictionary
+}
+
+
+# function that returns a team's game log in a given season
+def get_team_game_log(team: str, season: int) -> pd.DataFrame:
+    # make HTTP request and extract HTML
+    r = make_request(team, season)
+
+    # parse HTML using BeautifulSoup
+    soup = get_soup(r)
+
+    # collect data and return data frame
+    return collect_data(soup, season, team)
+
+
+def make_request(team: str, season: int):
+    url = 'https://pro-football-reference.com/teams/%s/%s.htm' % (team_hrefs[team], str(season))
+    return requests.get(url)
+
+
+def get_soup(request) -> BeautifulSoup:
+    return BeautifulSoup(request.text, 'html.parser')
+
+
+def collect_data(soup: BeautifulSoup, season: int, team: str) -> pd.DataFrame:
+    # set up data frame
+    data = {
+        'week': [],
+        'day': [],
+        'rest_days': [],
+        'home_team': [],
+        'distance_travelled': [],
+        'opp': [],
+        'result': [],
+        'points_for': [],
+        'points_allowed': [],
+        'tot_yds': [],
+        'pass_yds': [],
+        'rush_yds': [],
+        'opp_tot_yds': [],
+        'opp_pass_yds': [],
+        'opp_rush_yds': [],
+    }
+    df = pd.DataFrame(data)
+
+    # loading game data
+    games = soup.find_all('tbody')[1].find_all('tr')
+
+    # remove playoff games
+    j = 0
+    while j < len(games) and games[j].find('td', {'data-stat': 'game_date'}).text != 'Playoffs':
+        j += 1
+    for k in range(j, len(games)):
+        games.pop()
+
+    # remove bye week
+    j = 0
+    while games[j].find('td', {'data-stat': 'opp'}).text != 'Bye Week':
+        j += 1
+    games.pop(j)
+
+    # remove canceled games
+    to_delete = []
+    for j in range(len(games)):
+        if games[j].find('td', {'data-stat': 'boxscore_word'}).text == 'canceled':
+            to_delete.append(j)
+    for k in to_delete:
+        games.pop(k)
+
+    # 1993 had two bye weeks
+    if season == 1993:
+        while games[j].find('td', {'data-stat': 'opp'}).text != 'Bye Week':
+            j += 1
+        games.pop(j)
+
+    # gathering data
+    for i in range(len(games)):
+        week = int(games[i].find('th', {'data-stat': 'week_num'}).text)
+        day = games[i].find('td', {'data-stat': 'game_day_of_week'}).text
+        if i > 0:
+            if games[i - 1].find('td', {'data-stat': 'opp'}).text == 'Bye Week':
+                date1 = games[i - 2].find('td', {'data-stat': 'game_date'}).text.split(' ')
+                date2 = games[i].find('td', {'data-stat': 'game_date'}).text.split(' ')
+            else:
+                date1 = games[i - 1].find('td', {'data-stat': 'game_date'}).text.split(' ')
+                date2 = games[i].find('td', {'data-stat': 'game_date'}).text.split(' ')
+            if date1[0] == 'January':
+                rest_days = date(season + 1, months[date2[0]], int(date2[1])) - date(
+                    season + 1, months[date1[0]], int(date1[1])
+                )
+            elif date2[0] == 'January':
+                rest_days = date(season + 1, months[date2[0]], int(date2[1])) - date(
+                    season, months[date1[0]], int(date1[1])
+                )
+            else:
+                rest_days = date(season + 1, months[date2[0]], int(date2[1])) - date(
+                    season + 1, months[date1[0]], int(date1[1])
+                )
+        else:
+            rest_days = date(2022, 7, 11) - date(2022, 7, 1)  # setting first game as 10 rest days
+
+        opp = games[i].find('td', {'data-stat': 'opp'}).text
+
+        if games[i].find('td', {'data-stat': 'game_location'}).text == '@':
+            home_team = False
+            distance_travelled = calculate_distance(locations[cities[team]], locations[cities[opp]])
+        else:
+            home_team = True
+            distance_travelled = 0
+
+        result = games[i].find('td', {'data-stat': 'game_outcome'}).text
+        points_for = int(games[i].find('td', {'data-stat': 'pts_off'}).text)
+        points_allowed = int(games[i].find('td', {'data-stat': 'pts_def'}).text)
+        tot_yds = int(games[i].find('td', {'data-stat': 'yards_off'}).text)
+        pass_yds = int(games[i].find('td', {'data-stat': 'pass_yds_off'}).text)
+        rush_yds = int(games[i].find('td', {'data-stat': 'rush_yds_off'}).text)
+        opp_tot_yds = int(games[i].find('td', {'data-stat': 'yards_def'}).text)
+        opp_pass_yds = int(games[i].find('td', {'data-stat': 'pass_yds_def'}).text)
+        opp_rush_yds = int(games[i].find('td', {'data-stat': 'rush_yds_def'}).text)
+
+        # add row to data frame
+        df.loc[len(df.index)] = [
+            week,
+            day,
+            rest_days,
+            home_team,
+            distance_travelled,
+            opp,
+            result,
+            points_for,
+            points_allowed,
+            tot_yds,
+            pass_yds,
+            rush_yds,
+            opp_tot_yds,
+            opp_pass_yds,
+            opp_rush_yds,
+        ]
+
+    return df
+
+
+def calculate_distance(city1: dict, city2: dict) -> float:
+    coordinates1 = (city1['latitude'], city1['longitude'])
+    coordinates2 = (city2['latitude'], city2['longitude'])
+    return haversine(coordinates1, coordinates2, unit=Unit.MILES)
+
+
+def main():
+    print(get_team_game_log('Buffalo Bills', 2022))
+
+
+if __name__ == '__main__':
+    main()


Test patch:
diff --git a/tests/integration/test_team_game_log.py b/tests/integration/test_team_game_log.py
new file mode 100644
index 0000000..b588a4a
--- /dev/null
+++ b/tests/integration/test_team_game_log.py
@@ -0,0 +1,20 @@
+from src import team_game_log as t
+
+
+class TestClass:
+    # INTEGRATION TESTS
+    def test_get_team_game_log(self):
+        bills_game_log = t.get_team_game_log('Buffalo Bills', 2022)
+
+        # the Bills only played 16 games in 2022 due to the cancellation of their Week 17 game
+        assert len(bills_game_log.index) == 16
+
+        # the Bills recorded 6361 total yards in 2022
+        assert bills_game_log['tot_yds'].sum() == 6361
+
+        w = 0
+        for index, row in bills_game_log.iterrows():
+            if row['result'] == 'W':
+                w += 1
+        # the Bills won 13 games in 2022
+        assert w == 13
diff --git a/tests/unit/test_team_game_log.py b/tests/unit/test_team_game_log.py
new file mode 100644
index 0000000..a6c1657
--- /dev/null
+++ b/tests/unit/test_team_game_log.py
@@ -0,0 +1,386 @@
+from src import team_game_log as t
+from bs4 import BeautifulSoup
+from unittest.mock import MagicMock, patch
+
+
+class TestClass:
+    # UNIT TESTS ------------------------- #
+
+    def test_make_request(self):
+        response = t.make_request('Kansas City Chiefs', 2022)
+        # asserting that the HTTP request was made with the correct url
+        assert response.url == 'https://www.pro-football-reference.com/teams/kan/2022.htm'
+
+    @patch('requests.get')
+    def test_get_soup(self, mock_requests):
+        # mocking HTTP response
+        mock_response = MagicMock()
+        mock_response.text = "<!DOCTYPE html>\n"
+        soup = t.get_soup(mock_response)
+        # asserting that the soup text and mock response text are the same
+        assert mock_response.text == soup.prettify()
+
+    def test_collect_data(self):
+        # HTML from Kansas City Chiefs 2022 season to create BeautifulSoup object
+        fake_html = """<tbody></table>
+        <tbody>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="1" >1</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2022-09-11" >September 11</td>
+        <td class="right " data-stat="game_time" csk="16.25" >4:25PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202209110crd.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >1-0</td><td class="right " data-stat="game_location" >@</td>
+        <td class="left " data-stat="opp" ><a href="/teams/crd/2022.htm">Arizona Cardinals</a></td>
+        <td class="right " data-stat="pts_off" >44</td><td class="right " data-stat="pts_def" >21</td>
+        <td class="right " data-stat="first_down_off" >33</td><td class="right " data-stat="yards_off" >488</td>
+        <td class="right " data-stat="pass_yds_off" >360</td><td class="right " data-stat="rush_yds_off" >128</td>
+        <td class="right " data-stat="to_off" >1</td><td class="right " data-stat="first_down_def" >18</td>
+        <td class="right " data-stat="yards_def" >282</td><td class="right " data-stat="pass_yds_def" >179</td>
+        <td class="right " data-stat="rush_yds_def" >103</td><td class="right iz" data-stat="to_def" ></td>
+        <td class="right " data-stat="exp_pts_off" >33.41</td><td class="right " data-stat="exp_pts_def" >-2.29</td>
+        <td class="right " data-stat="exp_pts_st" >-6.88</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="2" >2</th>
+        <td class="left " data-stat="game_day_of_week" >Thu</td>
+        <td class="left " data-stat="game_date" csk="2022-09-15" >September 15</td>
+        <td class="right " data-stat="game_time" csk="20.15" >8:15PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202209150kan.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >2-0</td><td class="right iz" data-stat="game_location" ></td>
+        <td class="left " data-stat="opp" ><a href="/teams/sdg/2022.htm">Los Angeles Chargers</a></td>
+        <td class="right " data-stat="pts_off" >27</td><td class="right " data-stat="pts_def" >24</td>
+        <td class="right " data-stat="first_down_off" >15</td><td class="right " data-stat="yards_off" >319</td>
+        <td class="right " data-stat="pass_yds_off" >226</td><td class="right " data-stat="rush_yds_off" >93</td>
+        <td class="right iz" data-stat="to_off" ></td><td class="right " data-stat="first_down_def" >21</td>
+        <td class="right " data-stat="yards_def" >401</td><td class="right " data-stat="pass_yds_def" >326</td>
+        <td class="right " data-stat="rush_yds_def" >75</td><td class="right " data-stat="to_def" >1</td>
+        <td class="right " data-stat="exp_pts_off" >5.54</td><td class="right " data-stat="exp_pts_def" >-4.12</td>
+        <td class="right " data-stat="exp_pts_st" >3.72</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="3" >3</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2022-09-25" >September 25</td>
+        <td class="right " data-stat="game_time" csk="13.00" >1:00PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202209250clt.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >L</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >2-1</td><td class="right " data-stat="game_location" >@</td>
+        <td class="left " data-stat="opp" ><a href="/teams/clt/2022.htm">Indianapolis Colts</a></td>
+        <td class="right " data-stat="pts_off" >17</td><td class="right " data-stat="pts_def" >20</td>
+        <td class="right " data-stat="first_down_off" >20</td><td class="right " data-stat="yards_off" >315</td>
+        <td class="right " data-stat="pass_yds_off" >257</td><td class="right " data-stat="rush_yds_off" >58</td>
+        <td class="right " data-stat="to_off" >2</td><td class="right " data-stat="first_down_def" >19</td>
+        <td class="right " data-stat="yards_def" >259</td><td class="right " data-stat="pass_yds_def" >177</td>
+        <td class="right " data-stat="rush_yds_def" >82</td><td class="right " data-stat="to_def" >1</td>
+        <td class="right " data-stat="exp_pts_off" >1.78</td><td class="right " data-stat="exp_pts_def" >7.10</td>
+        <td class="right " data-stat="exp_pts_st" >-13.31</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="4" >4</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2022-10-02" >October 2</td>
+        <td class="right " data-stat="game_time" csk="20.20" >8:20PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202210020tam.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >3-1</td><td class="right " data-stat="game_location" >@</td>
+        <td class="left " data-stat="opp" ><a href="/teams/tam/2022.htm">Tampa Bay Buccaneers</a></td>
+        <td class="right " data-stat="pts_off" >41</td><td class="right " data-stat="pts_def" >31</td>
+        <td class="right " data-stat="first_down_off" >27</td><td class="right " data-stat="yards_off" >417</td>
+        <td class="right " data-stat="pass_yds_off" >228</td><td class="right " data-stat="rush_yds_off" >189</td>
+        <td class="right " data-stat="to_off" >1</td><td class="right " data-stat="first_down_def" >27</td>
+        <td class="right " data-stat="yards_def" >376</td><td class="right " data-stat="pass_yds_def" >373</td>
+        <td class="right " data-stat="rush_yds_def" >3</td><td class="right " data-stat="to_def" >2</td>
+        <td class="right " data-stat="exp_pts_off" >17.12</td><td class="right " data-stat="exp_pts_def" >-14.15</td>
+        <td class="right " data-stat="exp_pts_st" >5.33</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="5" >5</th>
+        <td class="left " data-stat="game_day_of_week" >Mon</td>
+        <td class="left " data-stat="game_date" csk="2022-10-10" >October 10</td>
+        <td class="right " data-stat="game_time" csk="20.15" >8:15PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202210100kan.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >4-1</td><td class="right iz" data-stat="game_location" ></td>
+        <td class="left " data-stat="opp" ><a href="/teams/rai/2022.htm">Las Vegas Raiders</a></td>
+        <td class="right " data-stat="pts_off" >30</td><td class="right " data-stat="pts_def" >29</td>
+        <td class="right " data-stat="first_down_off" >29</td><td class="right " data-stat="yards_off" >368</td>
+        <td class="right " data-stat="pass_yds_off" >265</td><td class="right " data-stat="rush_yds_off" >103</td>
+        <td class="right iz" data-stat="to_off" ></td><td class="right " data-stat="first_down_def" >18</td>
+        <td class="right " data-stat="yards_def" >378</td><td class="right " data-stat="pass_yds_def" >223</td>
+        <td class="right " data-stat="rush_yds_def" >155</td><td class="right iz" data-stat="to_def" ></td>
+        <td class="right " data-stat="exp_pts_off" >14.21</td><td class="right " data-stat="exp_pts_def" >-11.65</td>
+        <td class="right " data-stat="exp_pts_st" >0.35</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="6" >6</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2022-10-16" >October 16</td>
+        <td class="right " data-stat="game_time" csk="16.25" >4:25PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202210160kan.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >L</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >4-2</td><td class="right iz" data-stat="game_location" ></td>
+        <td class="left " data-stat="opp" ><a href="/teams/buf/2022.htm">Buffalo Bills</a></td>
+        <td class="right " data-stat="pts_off" >20</td><td class="right " data-stat="pts_def" >24</td>
+        <td class="right " data-stat="first_down_off" >23</td><td class="right " data-stat="yards_off" >387</td>
+        <td class="right " data-stat="pass_yds_off" >319</td><td class="right " data-stat="rush_yds_off" >68</td>
+        <td class="right " data-stat="to_off" >2</td><td class="right " data-stat="first_down_def" >26</td>
+        <td class="right " data-stat="yards_def" >443</td><td class="right " data-stat="pass_yds_def" >318</td>
+        <td class="right " data-stat="rush_yds_def" >125</td><td class="right " data-stat="to_def" >1</td>
+        <td class="right " data-stat="exp_pts_off" >6.45</td><td class="right " data-stat="exp_pts_def" >-11.13</td>
+        <td class="right " data-stat="exp_pts_st" >-0.56</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="7" >7</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2022-10-23" >October 23</td>
+        <td class="right " data-stat="game_time" csk="16.25" >4:25PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202210230sfo.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >5-2</td><td class="right " data-stat="game_location" >@</td>
+        <td class="left " data-stat="opp" ><a href="/teams/sfo/2022.htm">San Francisco 49ers</a></td>
+        <td class="right " data-stat="pts_off" >44</td><td class="right " data-stat="pts_def" >23</td>
+        <td class="right " data-stat="first_down_off" >24</td><td class="right " data-stat="yards_off" >529</td>
+        <td class="right " data-stat="pass_yds_off" >417</td><td class="right " data-stat="rush_yds_off" >112</td>
+        <td class="right " data-stat="to_off" >2</td><td class="right " data-stat="first_down_def" >25</td>
+        <td class="right " data-stat="yards_def" >444</td><td class="right " data-stat="pass_yds_def" >343</td>
+        <td class="right " data-stat="rush_yds_def" >101</td><td class="right " data-stat="to_def" >3</td>
+        <td class="right " data-stat="exp_pts_off" >30.58</td><td class="right " data-stat="exp_pts_def" >-3.59</td>
+        <td class="right " data-stat="exp_pts_st" >-8.50</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="7.8" >8</th>
+        <td class="left iz" data-stat="game_day_of_week" ></td><td class="left iz" data-stat="game_date" ></td>
+        <td class="right iz" data-stat="game_time" ></td><td class="center iz" data-stat="boxscore_word" ></td>
+        <td class="right iz" data-stat="game_outcome" ></td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center iz" data-stat="team_record" ></td><td class="right iz" data-stat="game_location" ></td>
+        <td class="left " data-stat="opp" ><strong>Bye Week</strong></td><td class="right iz" data-stat="pts_off" ></td>
+        <td class="right iz" data-stat="pts_def" ></td><td class="right iz" data-stat="first_down_off" ></td>
+        <td class="right iz" data-stat="yards_off" ></td><td class="right iz" data-stat="pass_yds_off" ></td>
+        <td class="right iz" data-stat="rush_yds_off" ></td><td class="right iz" data-stat="to_off" ></td>
+        <td class="right iz" data-stat="first_down_def" ></td><td class="right iz" data-stat="yards_def" ></td>
+        <td class="right iz" data-stat="pass_yds_def" ></td><td class="right iz" data-stat="rush_yds_def" ></td>
+        <td class="right iz" data-stat="to_def" ></td><td class="right iz" data-stat="exp_pts_off" ></td>
+        <td class="right iz" data-stat="exp_pts_def" ></td><td class="right iz" data-stat="exp_pts_st" ></td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="9" >9</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2022-11-06" >November 6</td>
+        <td class="right " data-stat="game_time" csk="20.20" >8:20PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202211060kan.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left " data-stat="overtime" >OT</td>
+        <td class="center " data-stat="team_record" >6-2</td><td class="right iz" data-stat="game_location" ></td>
+        <td class="left " data-stat="opp" ><a href="/teams/oti/2022.htm">Tennessee Titans</a></td>
+        <td class="right " data-stat="pts_off" >20</td><td class="right " data-stat="pts_def" >17</td>
+        <td class="right " data-stat="first_down_off" >29</td><td class="right " data-stat="yards_off" >499</td>
+        <td class="right " data-stat="pass_yds_off" >422</td><td class="right " data-stat="rush_yds_off" >77</td>
+        <td class="right " data-stat="to_off" >1</td><td class="right " data-stat="first_down_def" >9</td>
+        <td class="right " data-stat="yards_def" >229</td><td class="right " data-stat="pass_yds_def" >57</td>
+        <td class="right " data-stat="rush_yds_def" >172</td><td class="right iz" data-stat="to_def" ></td>
+        <td class="right " data-stat="exp_pts_off" >5.59</td><td class="right " data-stat="exp_pts_def" >3.85</td>
+        <td class="right " data-stat="exp_pts_st" >-5.59</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="10" >10</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2022-11-13" >November 13</td>
+        <td class="right " data-stat="game_time" csk="13.00" >1:00PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202211130kan.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >7-2</td><td class="right iz" data-stat="game_location" ></td>
+        <td class="left " data-stat="opp" ><a href="/teams/jax/2022.htm">Jacksonville Jaguars</a></td>
+        <td class="right " data-stat="pts_off" >27</td><td class="right " data-stat="pts_def" >17</td>
+        <td class="right " data-stat="first_down_off" >26</td><td class="right " data-stat="yards_off" >486</td>
+        <td class="right " data-stat="pass_yds_off" >331</td><td class="right " data-stat="rush_yds_off" >155</td>
+        <td class="right " data-stat="to_off" >3</td><td class="right " data-stat="first_down_def" >17</td>
+        <td class="right " data-stat="yards_def" >315</td><td class="right " data-stat="pass_yds_def" >240</td>
+        <td class="right " data-stat="rush_yds_def" >75</td><td class="right iz" data-stat="to_def" ></td>
+        <td class="right " data-stat="exp_pts_off" >23.27</td><td class="right " data-stat="exp_pts_def" >-3.86</td>
+        <td class="right " data-stat="exp_pts_st" >-7.32</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="11" >11</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2022-11-20" >November 20</td>
+        <td class="right " data-stat="game_time" csk="20.20" >8:20PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202211200sdg.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >8-2</td><td class="right " data-stat="game_location" >@</td>
+        <td class="left " data-stat="opp" ><a href="/teams/sdg/2022.htm">Los Angeles Chargers</a></td>
+        <td class="right " data-stat="pts_off" >30</td><td class="right " data-stat="pts_def" >27</td>
+        <td class="right " data-stat="first_down_off" >23</td><td class="right " data-stat="yards_off" >485</td>
+        <td class="right " data-stat="pass_yds_off" >322</td><td class="right " data-stat="rush_yds_off" >163</td>
+        <td class="right " data-stat="to_off" >1</td><td class="right " data-stat="first_down_def" >22</td>
+        <td class="right " data-stat="yards_def" >365</td><td class="right " data-stat="pass_yds_def" >250</td>
+        <td class="right " data-stat="rush_yds_def" >115</td><td class="right " data-stat="to_def" >2</td>
+        <td class="right " data-stat="exp_pts_off" >19.64</td><td class="right " data-stat="exp_pts_def" >-8.61</td>
+        <td class="right " data-stat="exp_pts_st" >-2.61</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="12" >12</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2022-11-27" >November 27</td>
+        <td class="right " data-stat="game_time" csk="16.25" >4:25PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202211270kan.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >9-2</td><td class="right iz" data-stat="game_location" ></td>
+        <td class="left " data-stat="opp" ><a href="/teams/ram/2022.htm">Los Angeles Rams</a></td>
+        <td class="right " data-stat="pts_off" >26</td><td class="right " data-stat="pts_def" >10</td>
+        <td class="right " data-stat="first_down_off" >29</td><td class="right " data-stat="yards_off" >437</td>
+        <td class="right " data-stat="pass_yds_off" >320</td><td class="right " data-stat="rush_yds_off" >117</td>
+        <td class="right " data-stat="to_off" >2</td><td class="right " data-stat="first_down_def" >13</td>
+        <td class="right " data-stat="yards_def" >198</td><td class="right " data-stat="pass_yds_def" >82</td>
+        <td class="right " data-stat="rush_yds_def" >116</td><td class="right " data-stat="to_def" >2</td>
+        <td class="right " data-stat="exp_pts_off" >13.96</td><td class="right " data-stat="exp_pts_def" >9.01</td>
+        <td class="right " data-stat="exp_pts_st" >-8.76</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="13" >13</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2022-12-04" >December 4</td>
+        <td class="right " data-stat="game_time" csk="16.25" >4:25PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202212040cin.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >L</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >9-3</td><td class="right " data-stat="game_location" >@</td>
+        <td class="left " data-stat="opp" ><a href="/teams/cin/2022.htm">Cincinnati Bengals</a></td>
+        <td class="right " data-stat="pts_off" >24</td><td class="right " data-stat="pts_def" >27</td>
+        <td class="right " data-stat="first_down_off" >20</td><td class="right " data-stat="yards_off" >349</td>
+        <td class="right " data-stat="pass_yds_off" >211</td><td class="right " data-stat="rush_yds_off" >138</td>
+        <td class="right " data-stat="to_off" >1</td><td class="right " data-stat="first_down_def" >26</td>
+        <td class="right " data-stat="yards_def" >431</td><td class="right " data-stat="pass_yds_def" >279</td>
+        <td class="right " data-stat="rush_yds_def" >152</td><td class="right iz" data-stat="to_def" ></td>
+        <td class="right " data-stat="exp_pts_off" >16.21</td><td class="right " data-stat="exp_pts_def" >-19.79</td>
+        <td class="right " data-stat="exp_pts_st" >-1.75</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="14" >14</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2022-12-11" >December 11</td>
+        <td class="right " data-stat="game_time" csk="16.20" >4:20PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202212110den.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >10-3</td><td class="right " data-stat="game_location" >@</td>
+        <td class="left " data-stat="opp" ><a href="/teams/den/2022.htm">Denver Broncos</a></td>
+        <td class="right " data-stat="pts_off" >34</td><td class="right " data-stat="pts_def" >28</td>
+        <td class="right " data-stat="first_down_off" >20</td><td class="right " data-stat="yards_off" >431</td>
+        <td class="right " data-stat="pass_yds_off" >342</td><td class="right " data-stat="rush_yds_off" >89</td>
+        <td class="right " data-stat="to_off" >3</td><td class="right " data-stat="first_down_def" >17</td>
+        <td class="right " data-stat="yards_def" >320</td><td class="right " data-stat="pass_yds_def" >214</td>
+        <td class="right " data-stat="rush_yds_def" >106</td><td class="right " data-stat="to_def" >2</td>
+        <td class="right " data-stat="exp_pts_off" >7.21</td><td class="right " data-stat="exp_pts_def" >0.63</td>
+        <td class="right " data-stat="exp_pts_st" >-0.09</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="15" >15</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2022-12-18" >December 18</td>
+        <td class="right " data-stat="game_time" csk="13.00" >1:00PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202212180htx.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left " data-stat="overtime" >OT</td>
+        <td class="center " data-stat="team_record" >11-3</td><td class="right " data-stat="game_location" >@</td>
+        <td class="left " data-stat="opp" ><a href="/teams/htx/2022.htm">Houston Texans</a></td>
+        <td class="right " data-stat="pts_off" >30</td><td class="right " data-stat="pts_def" >24</td>
+        <td class="right " data-stat="first_down_off" >33</td><td class="right " data-stat="yards_off" >502</td>
+        <td class="right " data-stat="pass_yds_off" >313</td><td class="right " data-stat="rush_yds_off" >189</td>
+        <td class="right " data-stat="to_off" >2</td><td class="right " data-stat="first_down_def" >18</td>
+        <td class="right " data-stat="yards_def" >219</td><td class="right " data-stat="pass_yds_def" >125</td>
+        <td class="right " data-stat="rush_yds_def" >94</td><td class="right " data-stat="to_def" >1</td>
+        <td class="right " data-stat="exp_pts_off" >13.62</td><td class="right " data-stat="exp_pts_def" >-2.21</td>
+        <td class="right " data-stat="exp_pts_st" >-6.34</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="16" >16</th>
+        <td class="left " data-stat="game_day_of_week" >Sat</td>
+        <td class="left " data-stat="game_date" csk="2022-12-24" >December 24</td>
+        <td class="right " data-stat="game_time" csk="13.00" >1:00PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202212240kan.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >12-3</td><td class="right iz" data-stat="game_location" ></td>
+        <td class="left " data-stat="opp" ><a href="/teams/sea/2022.htm">Seattle Seahawks</a></td>
+        <td class="right " data-stat="pts_off" >24</td><td class="right " data-stat="pts_def" >10</td>
+        <td class="right " data-stat="first_down_off" >14</td><td class="right " data-stat="yards_off" >297</td>
+        <td class="right " data-stat="pass_yds_off" >220</td><td class="right " data-stat="rush_yds_off" >77</td>
+        <td class="right iz" data-stat="to_off" ></td><td class="right " data-stat="first_down_def" >19</td>
+        <td class="right " data-stat="yards_def" >333</td><td class="right " data-stat="pass_yds_def" >200</td>
+        <td class="right " data-stat="rush_yds_def" >133</td><td class="right " data-stat="to_def" >1</td>
+        <td class="right " data-stat="exp_pts_off" >3.10</td><td class="right " data-stat="exp_pts_def" >11.64</td>
+        <td class="right " data-stat="exp_pts_st" >-2.23</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="17" >17</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2023-01-01" >January 1</td>
+        <td class="right " data-stat="game_time" csk="13.00" >1:00PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202301010kan.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >13-3</td><td class="right iz" data-stat="game_location" ></td>
+        <td class="left " data-stat="opp" ><a href="/teams/den/2022.htm">Denver Broncos</a></td>
+        <td class="right " data-stat="pts_off" >27</td><td class="right " data-stat="pts_def" >24</td>
+        <td class="right " data-stat="first_down_off" >22</td><td class="right " data-stat="yards_off" >374</td>
+        <td class="right " data-stat="pass_yds_off" >328</td><td class="right " data-stat="rush_yds_off" >46</td>
+        <td class="right " data-stat="to_off" >2</td><td class="right " data-stat="first_down_def" >21</td>
+        <td class="right " data-stat="yards_def" >307</td><td class="right " data-stat="pass_yds_def" >190</td>
+        <td class="right " data-stat="rush_yds_def" >117</td><td class="right " data-stat="to_def" >2</td>
+        <td class="right " data-stat="exp_pts_off" >10.69</td><td class="right " data-stat="exp_pts_def" >2.92</td>
+        <td class="right " data-stat="exp_pts_st" >-6.78</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="18" >18</th>
+        <td class="left " data-stat="game_day_of_week" >Sat</td>
+        <td class="left " data-stat="game_date" csk="2023-01-07" >January 7</td>
+        <td class="right " data-stat="game_time" csk="16.30" >4:30PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202301070rai.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >14-3</td><td class="right " data-stat="game_location" >@</td>
+        <td class="left " data-stat="opp" ><a href="/teams/rai/2022.htm">Las Vegas Raiders</a></td>
+        <td class="right " data-stat="pts_off" >31</td><td class="right " data-stat="pts_def" >13</td>
+        <td class="right " data-stat="first_down_off" >21</td><td class="right " data-stat="yards_off" >349</td>
+        <td class="right " data-stat="pass_yds_off" >181</td><td class="right " data-stat="rush_yds_off" >168</td>
+        <td class="right iz" data-stat="to_off" ></td><td class="right " data-stat="first_down_def" >21</td>
+        <td class="right " data-stat="yards_def" >279</td><td class="right " data-stat="pass_yds_def" >180</td>
+        <td class="right " data-stat="rush_yds_def" >99</td><td class="right " data-stat="to_def" >2</td>
+        <td class="right " data-stat="exp_pts_off" >16.83</td><td class="right " data-stat="exp_pts_def" >5.67</td>
+        <td class="right " data-stat="exp_pts_st" >-1.37</td></tr>
+        <tr ><th scope="row" class="right iz" data-stat="week_num" csk="17.5" ></th>
+        <td class="left iz" data-stat="game_day_of_week" ></td>
+        <td class="left " data-stat="game_date" ><strong>Playoffs</strong></td>
+        <td class="right iz" data-stat="game_time" ></td><td class="center iz" data-stat="boxscore_word" ></td>
+        <td class="right iz" data-stat="game_outcome" ></td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center iz" data-stat="team_record" ></td><td class="right iz" data-stat="game_location" ></td>
+        <td class="left iz" data-stat="opp" ></td><td class="right iz" data-stat="pts_off" ></td>
+        <td class="right iz" data-stat="pts_def" ></td><td class="right iz" data-stat="first_down_off" ></td>
+        <td class="right iz" data-stat="yards_off" ></td><td class="right iz" data-stat="pass_yds_off" ></td>
+        <td class="right iz" data-stat="rush_yds_off" ></td><td class="right iz" data-stat="to_off" ></td>
+        <td class="right iz" data-stat="first_down_def" ></td><td class="right iz" data-stat="yards_def" ></td>
+        <td class="right iz" data-stat="pass_yds_def" ></td><td class="right iz" data-stat="rush_yds_def" ></td>
+        <td class="right iz" data-stat="to_def" ></td><td class="right iz" data-stat="exp_pts_off" ></td>
+        <td class="right iz" data-stat="exp_pts_def" ></td><td class="right iz" data-stat="exp_pts_st" ></td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="20" >Division</th>
+        <td class="left " data-stat="game_day_of_week" >Sat</td>
+        <td class="left " data-stat="game_date" csk="2023-01-21" >January 21</td>
+        <td class="right " data-stat="game_time" csk="16.30" >4:30PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202301210kan.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >15-3</td><td class="right iz" data-stat="game_location" ></td>
+        <td class="left " data-stat="opp" ><a href="/teams/jax/2022.htm">Jacksonville Jaguars</a></td>
+        <td class="right " data-stat="pts_off" >27</td><td class="right " data-stat="pts_def" >20</td>
+        <td class="right " data-stat="first_down_off" >23</td><td class="right " data-stat="yards_off" >362</td>
+        <td class="right " data-stat="pass_yds_off" >218</td><td class="right " data-stat="rush_yds_off" >144</td>
+        <td class="right iz" data-stat="to_off" ></td><td class="right " data-stat="first_down_def" >20</td>
+        <td class="right " data-stat="yards_def" >349</td><td class="right " data-stat="pass_yds_def" >205</td>
+        <td class="right " data-stat="rush_yds_def" >144</td><td class="right " data-stat="to_def" >2</td>
+        <td class="right " data-stat="exp_pts_off" >13.73</td><td class="right " data-stat="exp_pts_def" >-4.86</td>
+        <td class="right " data-stat="exp_pts_st" >-0.10</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="21" >Conf. Champ.</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2023-01-29" >January 29</td>
+        <td class="right " data-stat="game_time" csk="18.30" >6:30PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202301290kan.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >16-3</td><td class="right iz" data-stat="game_location" ></td>
+        <td class="left " data-stat="opp" ><a href="/teams/cin/2022.htm">Cincinnati Bengals</a></td>
+        <td class="right " data-stat="pts_off" >23</td><td class="right " data-stat="pts_def" >20</td>
+        <td class="right " data-stat="first_down_off" >23</td><td class="right " data-stat="yards_off" >357</td>
+        <td class="right " data-stat="pass_yds_off" >315</td><td class="right " data-stat="rush_yds_off" >42</td>
+        <td class="right " data-stat="to_off" >1</td><td class="right " data-stat="first_down_def" >18</td>
+        <td class="right " data-stat="yards_def" >309</td><td class="right " data-stat="pass_yds_def" >238</td>
+        <td class="right " data-stat="rush_yds_def" >71</td><td class="right " data-stat="to_def" >2</td>
+        <td class="right " data-stat="exp_pts_off" >8.86</td><td class="right " data-stat="exp_pts_def" >-4.06</td>
+        <td class="right " data-stat="exp_pts_st" >-3.07</td></tr>
+        <tr ><th scope="row" class="right " data-stat="week_num" csk="22" >SuperBowl</th>
+        <td class="left " data-stat="game_day_of_week" >Sun</td>
+        <td class="left " data-stat="game_date" csk="2023-02-12" >February 12</td>
+        <td class="right " data-stat="game_time" csk="18.30" >6:30PM ET</td>
+        <td class="center " data-stat="boxscore_word" ><a href="/boxscores/202302120phi.htm">boxscore</a></td>
+        <td class="right " data-stat="game_outcome" >W</td><td class="left iz" data-stat="overtime" ></td>
+        <td class="center " data-stat="team_record" >17-3</td><td class="right " data-stat="game_location" >N</td>
+        <td class="left " data-stat="opp" ><a href="/teams/phi/2022.htm">Philadelphia Eagles</a></td>
+        <td class="right " data-stat="pts_off" >38</td><td class="right " data-stat="pts_def" >35</td>
+        <td class="right " data-stat="first_down_off" >21</td><td class="right " data-stat="yards_off" >340</td>
+        <td class="right " data-stat="pass_yds_off" >182</td><td class="right " data-stat="rush_yds_off" >158</td>
+        <td class="right iz" data-stat="to_off" ></td><td class="right " data-stat="first_down_def" >25</td>
+        <td class="right " data-stat="yards_def" >417</td><td class="right " data-stat="pass_yds_def" >302</td>
+        <td class="right " data-stat="rush_yds_def" >115</td><td class="right " data-stat="to_def" >1</td>
+        <td class="right " data-stat="exp_pts_off" >19.20</td><td class="right " data-stat="exp_pts_def" >-16.09</td>
+        <td class="right " data-stat="exp_pts_st" >0.10</td></tr>
+        </table>
+        """
+
+        soup = BeautifulSoup(fake_html, 'html.parser')
+        df = t.collect_data(soup, 2022, 'Kansas City Chiefs')
+        print(df)
+        # the Chiefs played in 17 regular season games and averaged ~29.2 points in those games
+        assert len(df.index) == 17 and int(df['points_for'].mean()) == 29
+
+    def test_calculate_distance(self):
+        city1 = {'latitude': 33.9416, 'longitude': 118.4085, 'airport': 'LAX'}
+        city2 = {'latitude': 40.4919, 'longitude': 80.2352, 'airport': 'PIT'}
+        assert int(t.calculate_distance(city1, city2)) == 2131