irongit

An AI project that includes a scraper for NFL data, postgres database, and user interface. It uses a classification algorithm to predict winners.

334 lines12 KB
1{
2 "cells": [
3 {
4 "cell_type": "markdown",
5 "metadata": {},
6 "source": [
7 "## 1. Set up the scraper\n",
8 "* Download data from nfl.com\n",
9 "* Use internal api with Bearer Key"
10 ]
11 },
12 {
13 "cell_type": "markdown",
14 "metadata": {},
15 "source": [
16 "### 1.1 Get a working example for Bearer token"
17 ]
18 },
19 {
20 "cell_type": "code",
21 "execution_count": 2,
22 "metadata": {},
23 "outputs": [],
24 "source": [
25 "import time\n",
26 "from browsermobproxy import Server\n",
27 "from selenium import webdriver\n",
28 "import json\n",
29 "import os\n",
30 "BMP_PATH = os.path.abspath('browsermob-proxy-2.1.4/bin/browsermob-proxy.bat')\n",
31 "\n",
32 "# Start BrowserMob Proxy\n",
33 "server = Server(BMP_PATH)\n",
34 "server.start()\n",
35 "proxy = server.create_proxy()\n",
36 "\n",
37 "# Configure Chrome with the proxy\n",
38 "chrome_options = webdriver.ChromeOptions()\n",
39 "chrome_options.add_argument(f'--proxy-server={proxy.proxy}')\n",
40 "chrome_options.add_argument('--ignore-certificate-errors')\n",
41 "chrome_options.add_argument('--headless')\n",
42 "driver = webdriver.Chrome(options=chrome_options)\n",
43 "# Navigate to the website\n",
44 "driver.get(\"https://nfl.com/scores\")\n",
45 "\n",
46 "# Start capturing network traffic\n",
47 "proxy.new_har(\"nfl\", options={'captureHeaders': True})\n",
48 "\n",
49 "# Wait for the header with the name \"Authorization\"\n",
50 "timeout = 60 # Adjust the timeout as needed\n",
51 "def get_auth_token():\n",
52 " start_time = time.time()\n",
53 " while time.time() - start_time < timeout:\n",
54 " har = proxy.har\n",
55 " for entry in har['log']['entries']:\n",
56 " request_headers = entry['request']['headers']\n",
57 " for header in request_headers:\n",
58 " if header['name'] == 'Authorization':\n",
59 " return header['value']\n",
60 " time.sleep(1)\n",
61 " return None\n",
62 "auth_token = get_auth_token()\n",
63 "\n",
64 "# Store the auth token\n",
65 "auth_path = 'auth.json'\n",
66 "auth_json = {\n",
67 " 'time': time.time(),\n",
68 " 'token': auth_token\n",
69 "}\n",
70 "with open(auth_path, 'w') as f:\n",
71 " json.dump(auth_json, f)\n",
72 "\n",
73 "# Stop capturing network traffic\n",
74 "har = proxy.har\n",
75 "\n",
76 "# Close the browser and BrowserMob Proxy\n",
77 "driver.quit()\n",
78 "server.stop()"
79 ]
80 },
81 {
82 "cell_type": "markdown",
83 "metadata": {},
84 "source": [
85 "### 1.2 Create a class that manages requests to nfl.com"
86 ]
87 },
88 {
89 "cell_type": "code",
90 "execution_count": 5,
91 "metadata": {},
92 "outputs": [],
93 "source": [
94 "from nfl_client import NFLClient\n",
95 "client = NFLClient(headless=True)"
96 ]
97 },
98 {
99 "cell_type": "code",
100 "execution_count": 7,
101 "metadata": {},
102 "outputs": [
103 {
104 "name": "stdout",
105 "output_type": "stream",
106 "text": [
107 "Auth Token: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjbGllbnRJZCI6ImU1MzVjN2MwLTgxN2YtNDc3Ni04OTkwLTU2NTU2ZjhiMTkyOCIsImNsaWVudEtleSI6IjRjRlVXNkRtd0pwelQ5TDdMckczcVJBY0FCRzVzMDRnIiwiaXNzIjoiTkZMIiwiZGV2aWNlSWQiOiI0YTIzZGM2My00YmQ2LTQ0OTMtYWVmNC0yNDk0OGRkNGMxYTUiLCJwbGFucyI6W3sicGxhbiI6ImZyZWUiLCJleHBpcmF0aW9uRGF0ZSI6IjIwMjQtMTEtMDQiLCJzb3VyY2UiOiJORkwiLCJzdGFydERhdGUiOiIyMDIzLTExLTA1Iiwic3RhdHVzIjoiQUNUSVZFIiwidHJpYWwiOmZhbHNlfV0sIkRpc3BsYXlOYW1lIjoiV0VCX0RFU0tUT1BfREVTS1RPUCIsIk5vdGVzIjoiIiwiZm9ybUZhY3RvciI6IkRFU0tUT1AiLCJsdXJhQXBwS2V5IjoiU1pzNTdkQkdSeGJMNzI4bFZwN0RZUSIsInBsYXRmb3JtIjoiREVTS1RPUCIsInByb2R1Y3ROYW1lIjoiV0VCIiwiY2l0eSI6ImFwcGxlIHZhbGxleSIsImNvdW50cnlDb2RlIjoiVVMiLCJkbWFDb2RlIjoiODAzIiwiaG1hVGVhbXMiOlsiMTA0MDI1MTAtODkzMS0wZDVmLTk4MTUtNzliYjc5NjQ5YTY1IiwiMTA0MDI1MjAtOTZiZi1lOWYyLTRmNjgtODUyMWNhODk2MDYwIiwiMTA0MDQ0MDAtM2IzNS0wNzNmLTE5N2UtMTk0YmI4MjQwNzIzIl0sInJlZ2lvbiI6IkNBIiwiYnJvd3NlciI6IkNocm9tZSBIZWFkbGVzcyIsImNlbGx1bGFyIjpmYWxzZSwiZW52aXJvbm1lbnQiOiJwcm9kdWN0aW9uIiwicm9sZXMiOlsiZnJlZSJdLCJleHAiOjE2OTkxNjQ3MTh9.l60UboGxeZ4ma5dfBircoc9ok_X25aerWyTFFxYTJjo\n"
108 ]
109 }
110 ],
111 "source": [
112 "client.load_auth_token(store_har=True)\n",
113 "print('Auth Token:', client.auth_token)"
114 ]
115 },
116 {
117 "cell_type": "markdown",
118 "metadata": {},
119 "source": [
120 "### 1.3 Convert har entry into json\n",
121 "1. Url to json\n",
122 "2. Convert har to json "
123 ]
124 },
125 {
126 "cell_type": "code",
127 "execution_count": 1,
128 "metadata": {},
129 "outputs": [
130 {
131 "data": {
132 "text/plain": [
133 "{'/football/v2/games/season/{season}/seasonType/REG/week/{week}': {'query_parameters': {},\n",
134 " 'path_parameters': {'season': {'type': 'integer', 'example': 2023},\n",
135 " 'week': {'type': 'integer', 'example': 9}}}}"
136 ]
137 },
138 "execution_count": 1,
139 "metadata": {},
140 "output_type": "execute_result"
141 }
142 ],
143 "source": [
144 "from nfl_client.url_utils import urlparse_json\n",
145 "url = '/football/v2/games/season/2023/seasonType/REG/week/9'\n",
146 "urlparse_json(url)"
147 ]
148 },
149 {
150 "cell_type": "code",
151 "execution_count": 5,
152 "metadata": {},
153 "outputs": [
154 {
155 "data": {
156 "text/plain": [
157 "{'/football/v2/games/season/{season}/blah/{blah_id}': {'query_parameters': {'withExternalIds': {'type': 'boolean',\n",
158 " 'example': 'true'}},\n",
159 " 'path_parameters': {'blah_id': {'type': 'string',\n",
160 " 'example': 'b07eaa67-f053-11ed-b4a7-bab79e4492fa'}},\n",
161 " 'response_sample': {'id': 'b07eaa67-f053-11ed-b4a7-bab79e4492fa',\n",
162 " 'homeTeam': {'id': '10402310-a47e-10ea-7442-16b633633637',\n",
163 " 'currentLogo': 'https://static.www.nfl.com/{formatInstructions}/league/api/clubs/logos/KC',\n",
164 " 'fullName': 'Kansas City Chiefs'},\n",
165 " 'awayTeam': {'id': '10402700-1662-d8ad-f45c-0b0ea460d045',\n",
166 " 'currentLogo': 'https://static.www.nfl.com/{formatInstructions}/league/api/clubs/logos/MIA',\n",
167 " 'fullName': 'Miami Dolphins'},\n",
168 " 'category': None,\n",
169 " 'date': '2023-11-05',\n",
170 " 'time': '2023-11-05T14:30:00Z',\n",
171 " 'broadcastInfo': {'homeNetworkChannels': ['NFL NETWORK'],\n",
172 " 'awayNetworkChannels': ['NFL NETWORK'],\n",
173 " 'internationalWatchOptions': [{'countryCode': 'CA',\n",
174 " 'broadcasters': ['DAZN Canada', 'RDS', 'TSN']},\n",
175 " {'countryCode': 'GB',\n",
176 " 'broadcasters': ['Sky Sports', 'NFL Game Pass on DAZN']},\n",
177 " {'countryCode': 'MX', 'broadcasters': ['NFL Game Pass on DAZN']},\n",
178 " {'countryCode': 'DE',\n",
179 " 'broadcasters': ['NFL Game Pass on DAZN', 'DAZN Germany (OTT)', 'RTL']},\n",
180 " {'countryCode': 'AU',\n",
181 " 'broadcasters': ['NFL Game Pass on DAZN', 'ESPN', 'TVNZ+']},\n",
182 " {'countryCode': 'FR',\n",
183 " 'broadcasters': ['NFL Game Pass on DAZN', 'beIN 2', '6Play']},\n",
184 " {'countryCode': 'BR',\n",
185 " 'broadcasters': ['NFL Game Pass on DAZN', 'ESPN2']}],\n",
186 " 'territory': 'NATIONAL'},\n",
187 " 'neutralSite': None,\n",
188 " 'venue': {'id': '00082031-5500-35b5-a67a-7f374ebf7168',\n",
189 " 'name': 'Frankfurt Stadium'},\n",
190 " 'season': 2023,\n",
191 " 'seasonType': 'REG',\n",
192 " 'status': 'SCHEDULED',\n",
193 " 'week': 9,\n",
194 " 'weekType': 'REG',\n",
195 " 'externalIds': [{'source': 'elias', 'id': '2023110500'},\n",
196 " {'source': 'gsis', 'id': '59296'},\n",
197 " {'source': 'slug', 'id': 'dolphins-at-chiefs-2023-reg-9'}],\n",
198 " 'ticketUrl': None,\n",
199 " 'ticketVendors': []}}}"
200 ]
201 },
202 "execution_count": 5,
203 "metadata": {},
204 "output_type": "execute_result"
205 }
206 ],
207 "source": [
208 "from nfl_client.url_utils import har_entry_parse\n",
209 "import json\n",
210 "with open('nfl_client_data/sample_har_entry.json', 'r') as f:\n",
211 " data = json.load(f)\n",
212 "\n",
213 "url_data = har_entry_parse(data)\n",
214 "url_data"
215 ]
216 },
217 {
218 "cell_type": "markdown",
219 "metadata": {},
220 "source": [
221 "#### 1.3.1 Create something to convert this into openapi"
222 ]
223 },
224 {
225 "cell_type": "code",
226 "execution_count": 6,
227 "metadata": {},
228 "outputs": [
229 {
230 "name": "stdout",
231 "output_type": "stream",
232 "text": [
233 "{'/football/v2/games/season/{season}/blah/{blah_id}': {'query_parameters': {'withExternalIds': {'type': 'boolean', 'example': 'true'}}, 'path_parameters': {'blah_id': {'type': 'string', 'example': 'b07eaa67-f053-11ed-b4a7-bab79e4492fa'}}, 'response_sample': {'id': 'b07eaa67-f053-11ed-b4a7-bab79e4492fa', 'homeTeam': {'id': '10402310-a47e-10ea-7442-16b633633637', 'currentLogo': 'https://static.www.nfl.com/{formatInstructions}/league/api/clubs/logos/KC', 'fullName': 'Kansas City Chiefs'}, 'awayTeam': {'id': '10402700-1662-d8ad-f45c-0b0ea460d045', 'currentLogo': 'https://static.www.nfl.com/{formatInstructions}/league/api/clubs/logos/MIA', 'fullName': 'Miami Dolphins'}, 'category': None, 'date': '2023-11-05', 'time': '2023-11-05T14:30:00Z', 'broadcastInfo': {'homeNetworkChannels': ['NFL NETWORK'], 'awayNetworkChannels': ['NFL NETWORK'], 'internationalWatchOptions': [{'countryCode': 'CA', 'broadcasters': ['DAZN Canada', 'RDS', 'TSN']}, {'countryCode': 'GB', 'broadcasters': ['Sky Sports', 'NFL Game Pass on DAZN']}, {'countryCode': 'MX', 'broadcasters': ['NFL Game Pass on DAZN']}, {'countryCode': 'DE', 'broadcasters': ['NFL Game Pass on DAZN', 'DAZN Germany (OTT)', 'RTL']}, {'countryCode': 'AU', 'broadcasters': ['NFL Game Pass on DAZN', 'ESPN', 'TVNZ+']}, {'countryCode': 'FR', 'broadcasters': ['NFL Game Pass on DAZN', 'beIN 2', '6Play']}, {'countryCode': 'BR', 'broadcasters': ['NFL Game Pass on DAZN', 'ESPN2']}], 'territory': 'NATIONAL'}, 'neutralSite': None, 'venue': {'id': '00082031-5500-35b5-a67a-7f374ebf7168', 'name': 'Frankfurt Stadium'}, 'season': 2023, 'seasonType': 'REG', 'status': 'SCHEDULED', 'week': 9, 'weekType': 'REG', 'externalIds': [{'source': 'elias', 'id': '2023110500'}, {'source': 'gsis', 'id': '59296'}, {'source': 'slug', 'id': 'dolphins-at-chiefs-2023-reg-9'}], 'ticketUrl': None, 'ticketVendors': []}}}\n"
234 ]
235 }
236 ],
237 "source": [
238 "from nfl_client.url_utils import generate_openapi_spec\n",
239 "\n",
240 "# Example\n",
241 "print(url_data)\n",
242 "openapi_yaml = generate_openapi_spec(url_data)\n",
243 "with open('openapi.yaml', 'w') as f:\n",
244 " f.write(openapi_yaml)"
245 ]
246 },
247 {
248 "cell_type": "markdown",
249 "metadata": {},
250 "source": [
251 "#### 1.3.2 Put it all together"
252 ]
253 },
254 {
255 "cell_type": "code",
256 "execution_count": 2,
257 "metadata": {},
258 "outputs": [
259 {
260 "data": {
261 "text/plain": [
262 "28"
263 ]
264 },
265 "execution_count": 2,
266 "metadata": {},
267 "output_type": "execute_result"
268 }
269 ],
270 "source": [
271 "from nfl_client import NFLClient\n",
272 "client = NFLClient()\n",
273 "url_json = client.download_endpoints()\n",
274 "len(url_json)"
275 ]
276 },
277 {
278 "cell_type": "markdown",
279 "metadata": {},
280 "source": [
281 "### 1.2 Get team data through the teams endpoint"
282 ]
283 },
284 {
285 "cell_type": "code",
286 "execution_count": 35,
287 "metadata": {},
288 "outputs": [
289 {
290 "data": {
291 "text/plain": [
292 "<Response [200]>"
293 ]
294 },
295 "execution_count": 35,
296 "metadata": {},
297 "output_type": "execute_result"
298 }
299 ],
300 "source": [
301 "api_url = 'https://api.nfl.com/football/v2/teams?limit=100&season=2023'\n",
302 "request(api_url)"
303 ]
304 },
305 {
306 "cell_type": "code",
307 "execution_count": null,
308 "metadata": {},
309 "outputs": [],
310 "source": []
311 }
312 ],
313 "metadata": {
314 "kernelspec": {
315 "display_name": "Python 3",
316 "language": "python",
317 "name": "python3"
318 },
319 "language_info": {
320 "codemirror_mode": {
321 "name": "ipython",
322 "version": 3
323 },
324 "file_extension": ".py",
325 "mimetype": "text/x-python",
326 "name": "python",
327 "nbconvert_exporter": "python",
328 "pygments_lexer": "ipython3",
329 "version": "3.10.9"
330 }
331 },
332 "nbformat": 4,
333 "nbformat_minor": 2
334}