Last active
November 7, 2024 16:01
-
-
Save tom-wagner/319d7f311b48a37f9e97b73c188b1372 to your computer and use it in GitHub Desktop.
Draftkings instructions
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
| // const axios = require('axios'); | |
| // const cheerio = require('cheerio'); | |
| // const fs = require('fs') | |
| // Set headers | |
| const headers = { | |
| "accept": "*/*", | |
| "accept-language": "en-US,en;q=0.9,la;q=0.8", | |
| // "priority": "u=1, i", | |
| "sec-ch-ua": "\"Chromium\";v=\"130\", \"Google Chrome\";v=\"130\", \"Not?A_Brand\";v=\"99\"", | |
| "sec-ch-ua-mobile": "?0", | |
| "sec-ch-ua-platform": "\"macOS\"", | |
| "sec-fetch-dest": "empty", | |
| "sec-fetch-mode": "cors", | |
| "sec-fetch-site": "same-site", | |
| // "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" | |
| }; | |
| // TODO: REFACTOR THIS --> SELECTIONS -> MARKETS -> EVENTS -> "name" | |
| // Key by the name of the game instead of team name | |
| // Function to fetch and extract team information for a player | |
| async function fetchPlayerTeam(url) { | |
| try { | |
| const response = await axios.get(url, { | |
| headers: headers, | |
| timeout: 10000 | |
| }); | |
| const html = response.data; | |
| const $ = cheerio.load(html); | |
| // Use Cheerio to search for the JSON data containing the player information | |
| const scriptTags = $('script').toArray(); | |
| let teamData = null; | |
| for (const script of scriptTags) { | |
| const scriptContent = $(script).html(); | |
| // Search for "playerBiometric" and parse its JSON structure | |
| if (scriptContent.includes('"playerBiometric"')) { | |
| const jsonMatch = scriptContent.match(/"playerBiometric":\s*(\{.*?\})/s); | |
| if (jsonMatch && jsonMatch[1]) { | |
| const abbreviationMatch = jsonMatch[1].match(/"abbreviation"\s*:\s*"([^"]+)"/); | |
| teamData = abbreviationMatch[1]; | |
| console.log(teamData) | |
| break; | |
| } | |
| } | |
| } | |
| if (teamData) { | |
| return teamData; | |
| } else { | |
| return null; | |
| } | |
| } catch (error) { | |
| console.error("Error fetching player data:", error.message || error); | |
| return null; | |
| } | |
| } | |
| const seenPlayerURL = {}; // Cache object to store seen player URLs and their team names | |
| async function scrapeSubCategory(category, id, subId) { | |
| const url = `https://sportsbook-nash.draftkings.com/api/sportscontent/dkusor/v1/leagues/42648/categories/${id}/subcategories/${subId}`; | |
| try { | |
| const response = await fetch(url, { | |
| headers: headers, | |
| timeout: 10000 | |
| }).then(r => r.json()); | |
| console.log({ response }); | |
| const output = {}; | |
| const selections = response['selections'] || []; | |
| for (const item of selections) { | |
| const playerId = item.participants[0].id; | |
| const playerName = item.participants[0].name.replace(' ', '-'); | |
| const seoIdentifier = item.participants[0].seoIdentifier; | |
| const playerURL = `https://sportsbook.draftkings.com/players/basketball/nba/${playerName}-odds-${playerId}`; | |
| let teamName; | |
| // Check if the player URL is in the cache | |
| if (seenPlayerURL[playerURL]) { | |
| teamName = seenPlayerURL[playerURL]; // Use cached team name | |
| console.log(`Using cached team name for ${playerURL}`); | |
| } else { | |
| // Fetch team name and cache it | |
| // teamName = await fetchPlayerTeam(playerURL); | |
| // seenPlayerURL[playerURL] = teamName; // Cache the result | |
| console.log(`Fetched and cached team name for ${playerURL}`); | |
| } | |
| // Initialize the team and player objects in output | |
| output[teamName] = output[teamName] || {}; | |
| const playerData = output[teamName][seoIdentifier] || (output[teamName][seoIdentifier] = {}); | |
| // Initialize the category object if it doesn't exist | |
| playerData[category] = playerData[category] || {}; | |
| playerData[category].line = item.points; | |
| if (item.displayOdds) { | |
| if (item.label === 'Over') { | |
| playerData[category].overOdds = item.displayOdds.american; | |
| } | |
| else if (item.label === 'Under') { | |
| playerData[category].underOdds = item.displayOdds.american; | |
| } | |
| } | |
| } | |
| // Display the output | |
| // console.log(JSON.stringify(output, null, 2)); | |
| return output; | |
| } catch (error) { | |
| console.error("Error fetching the data:", error.message || error); | |
| return null; | |
| } | |
| } | |
| const categories = [ | |
| ['PTS', 1215, 12488], | |
| ['REB', 1216, 12492], | |
| ['AST', 1217, 12495], | |
| ['3PM', 1218, 12497], | |
| ['PTS_REB_AST', 583, 5001], | |
| ['PTS_REB', 583, 9976], | |
| ['PTS_AST', 583, 9973], | |
| ['STEALS', 1293, 13508], | |
| ['BLOCKS', 1293, 13780], | |
| ['TURNOVERS', 1293, 13782], | |
| ['STEALS_BLOCKS', 1293, 13781], | |
| ]; | |
| async function scrapeAllCategories() { | |
| const finalOutput = {}; | |
| for (const [categoryName, id, subId] of categories) { | |
| const categoryData = await scrapeSubCategory(categoryName, id, subId); | |
| // Merge the data from this category into finalOutput | |
| for (const team in categoryData) { | |
| if (!finalOutput[team]) { | |
| finalOutput[team] = {}; | |
| } | |
| for (const player in categoryData[team]) { | |
| if (!finalOutput[team][player]) { | |
| finalOutput[team][player] = {}; | |
| } | |
| // Merge category data for the player | |
| finalOutput[team][player] = { | |
| ...finalOutput[team][player], | |
| ...categoryData[team][player] | |
| }; | |
| } | |
| } | |
| } | |
| console.log(JSON.stringify(finalOutput, null, 2)); | |
| // fs.writeFileSync('./result.json', JSON.stringify(finalOutput, null, 2)) | |
| return finalOutput; | |
| } | |
| scrapeAllCategories(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment