Skip to content

Instantly share code, notes, and snippets.

@tom-wagner
Last active November 7, 2024 16:01
Show Gist options
  • Save tom-wagner/319d7f311b48a37f9e97b73c188b1372 to your computer and use it in GitHub Desktop.
Save tom-wagner/319d7f311b48a37f9e97b73c188b1372 to your computer and use it in GitHub Desktop.
Draftkings instructions
// 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