Example #1
0
        protected override async Task ScrapeData()
        {
            const string url = "https://cds-api.borgataonline.com/bettingoffer/fixtures?x-bwin-accessid=ZTJhZDliYjgtNTdmOC00Njk0LWIxZmItODI3YzhjZGQ5NmIx&lang=en-US&country=VN&userCountry=VN&streamProviders=unas%2Cperform%2Cimgdge&fixtureTypes=Standard&state=Latest&skip=0&take=50&offerMapping=Filtered&offerCategories=Gridable&fixtureCategories=Gridable,NonGridable,Other&sortBy=Tags&sportIds=7&regionIds=9&competitionIds=6004";
            var          doc = await ScrapeHelper.GetDocument(url);

            var jDoc       = JsonConvert.DeserializeObject <JToken>(doc);
            var rawMatches = jDoc.SelectTokens("$.fixtures[*]");

            await UpdateScrapeStatus(10, "Scraping match data");

            var foundMatches = new List <Match>();

            foreach (var rawMatch in rawMatches)
            {
                var sourceId = rawMatch.SelectToken("$.id").ToString();
                if (string.IsNullOrEmpty(sourceId))
                {
                    Logger.Warning("Source match id is null");
                    continue;
                }
                var participants = rawMatch.SelectTokens("$.participants[*]").ToList();
                var homeTeam     = participants.Last().SelectToken("$.name.value").ToString();
                var awayTeam     = participants.First().SelectToken("$.name.value").ToString();

                var match = ScrapeHelper.FindMatchByHomeAndAwayTeam(TodayMatches, homeTeam, awayTeam);
                if (match == null)
                {
                    Logger.Warning($"Cannot find match with Home team: {homeTeam} and Away team: {awayTeam}");
                    continue;
                }

                match.SourceId = sourceId;
                foundMatches.Add(match);
            }
            await UpdateScrapeStatus(20, "Scrape match data complete");

            var rangeProgress = foundMatches.Count != 0 ? 90 / foundMatches.Count : 0;
            var currentRange  = 20;

            await UpdateScrapeStatus(20, "Scraping metric data");

            foreach (var match in foundMatches)
            {
                var metricUrl = $"https://cds-api.borgataonline.com/bettingoffer/fixture-view?x-bwin-accessid=ZTJhZDliYjgtNTdmOC00Njk0LWIxZmItODI3YzhjZGQ5NmIx&lang=en-US&country=VN&userCountry=VN&streamProviders=unas%2Cperform%2Cimgdge&offerMapping=All&scoreboardMode=Full&fixtureIds={match.SourceId}";
                doc = await ScrapeHelper.GetDocument(metricUrl);

                jDoc = JsonConvert.DeserializeObject <JToken>(doc);

                currentRange = Math.Min(currentRange + rangeProgress, 90);

                var rawMetrics = jDoc.SelectTokens("$.fixture.games[*]").ToList();
                foreach (var rawMetric in rawMetrics)
                {
                    var nameData  = rawMetric.SelectToken("$.name.value").ToString();
                    var scoreType =
                        nameData.Contains("How many points") ? ScoreType.Point :
                        nameData.Contains("How many assists") ? ScoreType.Assist :
                        nameData.Contains("How many rebounds") ? ScoreType.Rebound :
                        string.Empty;
                    if (string.IsNullOrEmpty(scoreType))
                    {
                        continue;
                    }

                    var playerName = ScrapeHelper.RegexMappingExpression(nameData, @".* will (.*) \(");
                    var player     = ScrapeHelper.FindPlayerInMatch(playerName, match);
                    if (player == null)
                    {
                        Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                        continue;
                    }

                    var overData     = rawMetric.SelectToken("$.results[0]");
                    var over         = ScrapeHelper.ConvertMetric(overData.SelectToken("$.odds").ToString());
                    var overLineData = overData.SelectToken("$.name.value").ToString();
                    var overLine     = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(overLineData, "Over (.*)"));

                    var underData     = rawMetric.SelectToken("$.results[0]");
                    var under         = ScrapeHelper.ConvertMetric(underData.SelectToken("$.odds").ToString());
                    var underLineData = underData.SelectToken("$.name.value").ToString();
                    var underLine     = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(underLineData, "Over (.*)"));

                    Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                    var metric = new PlayerOverUnder
                    {
                        MatchId               = match.Id,
                        Over                  = over,
                        OverLine              = overLine,
                        Under                 = under,
                        UnderLine             = underLine,
                        PlayerId              = player.Id,
                        ScoreType             = scoreType,
                        ScrapingInformationId = GetScrapingInformation().Id,
                        CreatedAt             = DateTime.Now
                    };

                    PlayerUnderOvers.Add(metric);

                    var newProgress = GetScrapingInformation().Progress;
                    newProgress = Math.Min(newProgress + currentRange / rawMetrics.Count, currentRange);
                    await UpdateScrapeStatus(newProgress, null);
                }
                await UpdateScrapeStatus(currentRange, null);
            }
            await UpdateScrapeStatus(90, "Scrape metric data complete");
        }
        protected override async Task ScrapeData()
        {
            const string url = "https://eu-offering.kambicdn.org/offering/v2018/888/listView/basketball.json?lang=en_GB&market=ZZ&client_id=2&channel_id=1&ncid=1572482733163&useCombined=true";
            var          doc = await ScrapeHelper.GetDocument(url);

            var jDoc       = JsonConvert.DeserializeObject <JToken>(doc);
            var rawMatches = jDoc.SelectTokens("$.events[?(@.event.group == 'NBA')]");

            await UpdateScrapeStatus(10, "Scraping match data");

            var foundMatches = new List <Match>();

            foreach (var rawMatch in rawMatches)
            {
                var sourceId = rawMatch.SelectToken("$.event.id").ToString();
                if (string.IsNullOrEmpty(sourceId))
                {
                    Logger.Warning("Source match id is null");
                    continue;
                }

                var homeTeam = rawMatch.SelectToken("$.event.homeName").ToString();
                var awayTeam = rawMatch.SelectToken("$.event.awayName").ToString();

                var match = ScrapeHelper.FindMatchByHomeAndAwayTeam(TodayMatches, homeTeam, awayTeam);
                if (match == null)
                {
                    Logger.Warning($"Cannot find match with Home team: {homeTeam} and Away team: {awayTeam}");
                    continue;
                }

                match.SourceId = sourceId;
                foundMatches.Add(match);
            }
            await UpdateScrapeStatus(20, "Scrape match data complete");

            await UpdateScrapeStatus(20, "Scraping metric data");

            var rangeProgress = foundMatches.Count != 0 ? 90 / foundMatches.Count : 0;
            var currentRange  = 20;

            foreach (var match in foundMatches)
            {
                var metricUrl = $"https://eu-offering.kambicdn.org/offering/v2018/888/betoffer/event/{match.SourceId}.json?lang=en_GB&market=ZZ&client_id=2&channel_id=1&ncid=1005710980&includeParticipants=true";
                doc = await ScrapeHelper.GetDocument(metricUrl);

                jDoc = JsonConvert.DeserializeObject <JToken>(doc);

                currentRange = Math.Min(currentRange + rangeProgress, 90);

                var rawMetrics = jDoc.SelectTokens("$.betOffers[*]").ToList();
                foreach (var rawMetric in rawMetrics)
                {
                    var labelData = rawMetric.SelectToken("$.criterion.label").ToString();
                    var scoreType = labelData.Contains("Points scored by the player") ? ScoreType.Point :
                                    labelData.Contains("Rebounds by the player") ? ScoreType.Rebound :
                                    labelData.Contains("Assists by the player") ? ScoreType.Assist :
                                    labelData.Contains("Points, rebounds & assists by the player") ? ScoreType.PointReboundAssist :
                                    labelData.Contains("3-point field goals made by the player") ? ScoreType.ThreePoint :
                                    string.Empty;

                    if (string.IsNullOrEmpty(scoreType))
                    {
                        continue;
                    }

                    var overData  = rawMetric.SelectToken("$.outcomes[?(@.label =~ /(Over.*)/)]");
                    var underData = rawMetric.SelectToken("$.outcomes[?(@.label =~ /(Under.*)/)]");

                    var playerData   = overData.SelectToken("$.participant").ToString();
                    var playerSplits = playerData.Split(',');
                    var rvPlayer     = playerSplits.Reverse().ToList();
                    var playerName   = string.Join(" ", rvPlayer);

                    var player = ScrapeHelper.FindPlayerInMatch(playerName, match);
                    if (player == null)
                    {
                        Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                        continue;
                    }

                    var overLineData = overData.SelectToken("$.label").ToString();
                    var overLine     = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(overLineData, @"Over.* (\d*.\d*)"));
                    var overOdd      = ScrapeHelper.ConvertMetric(overData.SelectToken("$.odds").ToString());
                    var over         = overOdd / 1000;

                    var underLineData = underData.SelectToken("$.label").ToString();
                    var underLine     = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(underLineData, @"Under.* (\d*.\d*)"));
                    var underOdd      = ScrapeHelper.ConvertMetric(underData.SelectToken("$.odds").ToString());
                    var under         = underOdd / 1000;

                    Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                    var metric = new PlayerOverUnder
                    {
                        MatchId               = match.Id,
                        Over                  = over,
                        OverLine              = overLine,
                        Under                 = under,
                        UnderLine             = underLine,
                        PlayerId              = player.Id,
                        ScoreType             = scoreType,
                        ScrapingInformationId = GetScrapingInformation().Id,
                        CreatedAt             = DateTime.Now
                    };

                    PlayerUnderOvers.Add(metric);

                    var newProgress = GetScrapingInformation().Progress;
                    newProgress = Math.Min(newProgress + currentRange / rawMetrics.Count, currentRange);
                    await UpdateScrapeStatus(newProgress, null);
                }
                await UpdateScrapeStatus(currentRange, null);
            }
            await UpdateScrapeStatus(90, "Scrape metric data complete");
        }
Example #3
0
        protected override async Task ScrapeData()
        {
            const string url = "https://services.bovada.lv/services/sports/event/coupon/events/A/description/basketball/nba?marketFilterId=def&preMatchOnly=true&lang=en";
            var          doc = await ScrapeHelper.GetDocument(url);

            var jDoc       = JsonConvert.DeserializeObject <JToken>(doc);
            var rawMatches = jDoc.SelectTokens("$.[*].events[*]");

            await UpdateScrapeStatus(10, "Scraping match data");

            var foundMatches = new List <Match>();

            foreach (var rawMatch in rawMatches)
            {
                var sourceId = rawMatch.SelectToken("$.link").ToString();
                if (string.IsNullOrEmpty(sourceId))
                {
                    Logger.Warning("Source match id is null");
                    continue;
                }
                var description = rawMatch.SelectToken("$.description").ToString();
                var desSplits   = description.Split('@');
                var homeTeam    = desSplits[1];
                var awayTeam    = desSplits[0];

                var match = ScrapeHelper.FindMatchByHomeAndAwayTeam(TodayMatches, homeTeam, awayTeam);
                if (match == null)
                {
                    Logger.Warning($"Cannot find match with Home team: {homeTeam} and Away team: {awayTeam}");
                    continue;
                }

                match.SourceId = sourceId;
                foundMatches.Add(match);
            }
            await UpdateScrapeStatus(20, "Scrape match data complete");

            var rangeProgress = foundMatches.Count != 0 ? 90 / foundMatches.Count : 0;
            var currentRange  = 20;

            await UpdateScrapeStatus(20, "Scraping metric data");

            foreach (var match in foundMatches)
            {
                var metricUrl = $"https://services.bovada.lv/services/sports/event/coupon/events/A/description{match.SourceId}?lang=en";
                doc = await ScrapeHelper.GetDocument(metricUrl);

                jDoc = JsonConvert.DeserializeObject <JToken>(doc);

                currentRange = Math.Min(currentRange + rangeProgress, 90);

                var rawMetrics = jDoc
                                 .SelectTokens("$.[*].events[*].displayGroups[?(@.description == 'Player Props')].markets[*]")
                                 .ToList();
                foreach (var rawMetric in rawMetrics)
                {
                    var description = rawMetric.SelectToken("$.description").ToString();
                    var scoreType   =
                        description.Contains("Total Points, Rebounds and Assists") ? ScoreType.PointReboundAssist :
                        description.Contains("Total Points and Rebounds") ? ScoreType.PointRebound :
                        description.Contains("Total Points and Assists") ? ScoreType.PointAssist :
                        description.Contains("Total Rebounds and Assists") ? ScoreType.ReboundAssist :
                        description.Contains("Total Points") ? ScoreType.Point :
                        description.Contains("Total Rebounds") ? ScoreType.Rebound :
                        description.Contains("Total Assists") ? ScoreType.Assist :
                        string.Empty;

                    if (string.IsNullOrEmpty(scoreType))
                    {
                        continue;
                    }

                    var playerName = ScrapeHelper.RegexMappingExpression(description, @"- (.*) \(");
                    var player     = ScrapeHelper.FindPlayerInMatch(playerName, match);
                    if (player == null)
                    {
                        Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                        continue;
                    }

                    var    outcomes = rawMetric.SelectTokens("$.outcomes[*]");
                    double?over = 0, overLine = 0, under = 0, underLine = 0;
                    foreach (var outcome in outcomes)
                    {
                        var des = outcome.SelectToken("$.description").ToString();
                        if (des.Contains("Over"))
                        {
                            overLine = ScrapeHelper.ConvertMetric(outcome.SelectToken("$.price.handicap").ToString());
                            var overPrice = ScrapeHelper.ConvertMetric(outcome.SelectToken("$.price.decimal").ToString());
                            over = overPrice != null?Math.Round((double)overPrice, 2) : (double?)null;
                        }
                        else if (des.Contains("Under"))
                        {
                            underLine = ScrapeHelper.ConvertMetric(outcome.SelectToken("$.price.handicap").ToString());
                            var underPrice = ScrapeHelper.ConvertMetric(outcome.SelectToken("$.price.decimal").ToString());
                            under = underPrice != null?Math.Round((double)underPrice, 2) : (double?)null;
                        }
                    }

                    Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                    var metric = new PlayerOverUnder
                    {
                        MatchId               = match.Id,
                        Over                  = over,
                        OverLine              = overLine,
                        Under                 = under,
                        UnderLine             = underLine,
                        PlayerId              = player.Id,
                        ScoreType             = scoreType,
                        ScrapingInformationId = GetScrapingInformation().Id,
                        CreatedAt             = DateTime.Now
                    };

                    PlayerUnderOvers.Add(metric);

                    var newProgress = GetScrapingInformation().Progress;
                    newProgress = Math.Min(newProgress + currentRange / rawMetrics.Count, currentRange);
                    await UpdateScrapeStatus(newProgress, null);
                }
                await UpdateScrapeStatus(currentRange, null);
            }
            await UpdateScrapeStatus(90, "Scrape metric data complete");
        }
        protected override async Task ScrapeData()
        {
            const string url    = "https://www.betvictor.com/api/top_bets/601600?number_to_show=20&exclude_in_running=true&event_ids_to_exclude=&sport_ids_to_exclude=";
            var          rawDoc = await ScrapeHelper.GetDocument(url);

            var jDoc = JsonConvert.DeserializeObject <JToken>(rawDoc);

            await UpdateScrapeStatus(10, "Scraping match data");

            var rawMatches   = jDoc.SelectTokens("$.[?(@.meeting_description == 'NBA')]");
            var foundMatches = new List <Match>();

            foreach (var rawMatch in rawMatches)
            {
                var sourceMatchId = rawMatch.SelectToken("$.event_id").ToString();
                if (string.IsNullOrEmpty(sourceMatchId))
                {
                    Logger.Warning("Source Id is null");
                    continue;
                }

                if (foundMatches.Select(x => x.SourceId).Contains(sourceMatchId))
                {
                    continue;
                }

                var game     = rawMatch.SelectToken("$.event_description").ToString();
                var clubs    = game.Split('@');
                var homeTeam = clubs[1];
                var awayTeam = clubs[0];

                var match = ScrapeHelper.FindMatchByHomeAndAwayTeam(TodayMatches, homeTeam, awayTeam);
                if (match == null)
                {
                    Logger.Warning($"Cannot find match with Home team: {homeTeam} and Away team: {awayTeam}");
                    continue;
                }

                match.SourceId = sourceMatchId;
                foundMatches.Add(match);
            }
            await UpdateScrapeStatus(20, "Scrape match data complete");

            var rangeProgress = foundMatches.Count != 0 ? 90 / foundMatches.Count : 0;
            var currentRange  = 20;

            await UpdateScrapeStatus(20, "Scraping metric data");

            foreach (var match in foundMatches)
            {
                rawDoc = await ScrapeHelper.GetDocument($"https://www.betvictor.com/bv_event_level/en-gb/1/coupons/{match.SourceId}/4787?t=1573192805056");

                var jResult = JsonConvert.DeserializeObject <JToken>(rawDoc);

                currentRange = Math.Min(currentRange + rangeProgress, 90);

                var rawMetrics = jResult.SelectTokens("$.[*].markets[*]").ToList();
                foreach (var rawMetric in rawMetrics)
                {
                    var description = rawMetric.SelectToken("$.des").ToString();
                    var scoreType   =
                        description.Contains("Total combined points, assists & rebounds") ? ScoreType.PointReboundAssist :
                        description.Contains("Total points") ? ScoreType.Point :
                        description.Contains("Total assists") ? ScoreType.Assist :
                        description.Contains("Total three pointers") ? ScoreType.ThreePoint :
                        description.Contains("Total rebounds") ? ScoreType.Rebound :
                        description.Contains("Total combined points & rebounds") ? ScoreType.PointRebound :
                        description.Contains("Total combined points & assists") ? ScoreType.PointAssist :
                        description.Contains("Total combined assists & rebounds") ? ScoreType.ReboundAssist :
                        string.Empty;

                    if (string.IsNullOrEmpty(scoreType))
                    {
                        continue;
                    }

                    var playerName = rawMetric.SelectToken("$.opponentDescription").ToString();
                    var player     = ScrapeHelper.FindPlayerInMatch(playerName, match);
                    if (player == null)
                    {
                        Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                        continue;
                    }

                    var playerMetrics = rawMetric.SelectTokens("$.o[*]");

                    double?over = 0, overLine = 0, under = 0, underLine = 0;
                    foreach (var metricItem in playerMetrics)
                    {
                        var des = metricItem.SelectToken("$.des").ToString();
                        if (des.Contains("Over"))
                        {
                            overLine = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(des, "Over (.*)"));
                            over     = ScrapeHelper.ConvertMetric(metricItem.SelectToken("$.pr").ToString());
                        }
                        else if (des.Contains("Under"))
                        {
                            underLine = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(des, "Under (.*)"));
                            under     = ScrapeHelper.ConvertMetric(metricItem.SelectToken("$.pr").ToString());
                        }
                    }

                    Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                    var metric = new PlayerOverUnder
                    {
                        PlayerId              = player.Id,
                        ScoreType             = scoreType,
                        ScrapingInformationId = GetScrapingInformation().Id,
                        MatchId   = match.Id,
                        Over      = over,
                        OverLine  = overLine,
                        Under     = under,
                        UnderLine = underLine,
                        CreatedAt = DateTime.Now
                    };

                    PlayerUnderOvers.Add(metric);

                    var newProgress = GetScrapingInformation().Progress;
                    newProgress = Math.Min(newProgress + currentRange / rawMetrics.Count, currentRange);
                    await UpdateScrapeStatus(newProgress, null);
                }
                await UpdateScrapeStatus(currentRange, null);
            }
            await UpdateScrapeStatus(90, "Scrape metric data complete");
        }
        protected override async Task ScrapeData()
        {
            const string url = "https://api.pointsbet.com/api/v2/competitions/7176/events/featured?includeLive=true";
            var          doc = await ScrapeHelper.GetDocument(url);

            var jDoc         = JsonConvert.DeserializeObject <JToken>(doc);
            var rawMatches   = jDoc.SelectTokens("$.events[*]");
            var foundMatches = new List <Match>();

            await UpdateScrapeStatus(10, "Scraping match data");

            Logger.Information("Scraping match data");
            foreach (var rawMatch in rawMatches)
            {
                var sourceId = rawMatch.SelectToken("$.key").ToString();
                if (string.IsNullOrEmpty(sourceId))
                {
                    Logger.Warning("Source Id is null");
                    continue;
                }
                var homeTeam = rawMatch.SelectToken("$.homeTeam").ToString();
                var awayTeam = rawMatch.SelectToken("$.awayTeam").ToString();
                var match    = ScrapeHelper.FindMatchByHomeAndAwayTeam(TodayMatches, homeTeam, awayTeam);

                if (match == null)
                {
                    Logger.Warning($"Cannot find match with Home team: {homeTeam} and Away team: {awayTeam}");
                    continue;
                }

                match.SourceId = sourceId;
                foundMatches.Add(match);
            }
            Logger.Information("Scrape match data complete");
            await UpdateScrapeStatus(20, "Scrape match data complete");

            await UpdateScrapeStatus(20, "Scraping metric data");

            var rangeProgress = foundMatches.Count != 0 ? 90 / foundMatches.Count : 0;
            var currentRange  = 20;

            Logger.Information("Scrape metric data");
            foreach (var match in foundMatches)
            {
                var metricUrl = $"https://api.pointsbet.com/api/v2/events/{match.SourceId}";
                doc = await ScrapeHelper.GetDocument(metricUrl);

                jDoc = JsonConvert.DeserializeObject <JToken>(doc);

                currentRange = Math.Min(currentRange + rangeProgress, 90);

                var rawMetrics = jDoc
                                 .SelectTokens(
                    @"$.fixedOddsMarkets[?(@.name =~ /(Player Points Over\/Under .*)/ || @.name =~ /(Player Rebounds Over\/Under .*)/ || @.name =~ /(Player Assists Over\/Under .*)/)]")
                                 .ToList();
                foreach (var rawMetric in rawMetrics)
                {
                    var metricName = rawMetric.SelectToken("$.name").ToString();
                    var scoreType  =
                        metricName.Contains("Player Points") ? ScoreType.Point :
                        metricName.Contains("Player Assists") ? ScoreType.Assist :
                        metricName.Contains("Player Rebounds") ? ScoreType.Rebound :
                        metricName.Contains("Player Pts + Rebs + Asts") ? ScoreType.PointReboundAssist :
                        string.Empty;

                    if (string.IsNullOrEmpty(scoreType))
                    {
                        continue;
                    }

                    var outcomeOvers  = rawMetric.SelectTokens("$.outcomes[?(@.name =~ /(.* Over .*)/)]").ToList();
                    var outcomeUnders = rawMetric.SelectTokens("$.outcomes[?(@.name =~ /(.* Under .*)/)]").ToList();

                    var playerNames = new HashSet <string>();

                    foreach (var name in outcomeOvers.Select(outcome => outcome.SelectToken("name").ToString()))
                    {
                        playerNames.Add(ScrapeHelper.RegexMappingExpression(name, "(.*)(?:Over|Under)"));
                    }

                    foreach (var name in outcomeUnders.Select(outcome => outcome.SelectToken("name").ToString()))
                    {
                        playerNames.Add(ScrapeHelper.RegexMappingExpression(name, "(.*)(?:Over|Under)"));
                    }

                    foreach (var playerName in playerNames)
                    {
                        var player = ScrapeHelper.FindPlayerInMatch(playerName, match);
                        if (player == null)
                        {
                            Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                            continue;
                        }

                        var outcomeOver = outcomeOvers.FirstOrDefault(x =>
                                                                      x.SelectToken("$.name").ToString().Contains(playerName));
                        var outcomeUnder = outcomeUnders.FirstOrDefault(x =>
                                                                        x.SelectToken("$.name").ToString().Contains(playerName));

                        var rawOver     = outcomeOver?.SelectToken("price").ToString();
                        var rawOverLine =
                            ScrapeHelper.RegexMappingExpression(outcomeOver?.SelectToken("$.name").ToString(),
                                                                "(?:Over) (.*)");

                        var rawUnder     = outcomeUnder?.SelectToken("price").ToString();
                        var rawUnderLine =
                            ScrapeHelper.RegexMappingExpression(outcomeUnder?.SelectToken("$.name").ToString(),
                                                                "(?:Under) (.*)");

                        Logger.Information($"{player.Name}: {scoreType} - {rawOver} {rawOverLine} | {rawUnder} {rawUnderLine}");

                        var metric = new PlayerOverUnder
                        {
                            MatchId               = match.Id,
                            Over                  = ScrapeHelper.ConvertMetric(rawOver),
                            OverLine              = ScrapeHelper.ConvertMetric(rawOverLine),
                            Under                 = ScrapeHelper.ConvertMetric(rawUnder),
                            UnderLine             = ScrapeHelper.ConvertMetric(rawUnderLine),
                            PlayerId              = player.Id,
                            ScoreType             = scoreType,
                            ScrapingInformationId = GetScrapingInformation().Id,
                            CreatedAt             = DateTime.Now
                        };

                        PlayerUnderOvers.Add(metric);

                        var newProgress = GetScrapingInformation().Progress;
                        newProgress = Math.Min(newProgress + currentRange / rawMetrics.Count, currentRange);
                        await UpdateScrapeStatus(newProgress, null);
                    }
                    await UpdateScrapeStatus(currentRange, null);
                }
            }
            Logger.Information("Scrape metric data complete");
            await UpdateScrapeStatus(90, "Scrape metric data complete");
        }
        protected override async Task ScrapeData()
        {
            const string url    = "https://betbuilder.digitalsportstech.com/api/latestGames?leagueId=123&sb=topsport&status=1";
            var          rawDoc = await ScrapeHelper.GetDocument(url);

            var jDoc = JsonConvert.DeserializeObject <JToken>(rawDoc);

            var rawMatches   = jDoc.SelectTokens("$.data[*]");
            var foundMatches = new List <Match>();

            await UpdateScrapeStatus(10, "Scraping match data");

            Logger.Information("Scraping match data");
            foreach (var rawMatch in rawMatches)
            {
                var sourceMatchId = rawMatch.SelectToken("$.id").ToString();
                if (string.IsNullOrEmpty(sourceMatchId))
                {
                    Logger.Warning("Source Id is null");
                    continue;
                }

                var homeTeam = rawMatch.SelectToken("$.homeTeam.title").ToString();
                var awayTeam = rawMatch.SelectToken("$.visitingTeam.title").ToString();

                var match = ScrapeHelper.FindMatchByHomeAndAwayTeam(TodayMatches, homeTeam, awayTeam);
                if (match == null)
                {
                    Logger.Warning($"Cannot find match with Home team: {homeTeam} and Away team: {awayTeam}");
                    continue;
                }

                match.SourceId = sourceMatchId;
                foundMatches.Add(match);
            }
            Logger.Information("Scrape match data complete");
            await UpdateScrapeStatus(20, "Scrape match data complete");

            await UpdateScrapeStatus(20, "Scraping metric data");

            var rangeProgress = foundMatches.Count != 0 ? 90 / foundMatches.Count : 0;
            var currentRange  = 20;

            Logger.Information("Scraping metric data");
            _rawData = new List <PlayerOverUnder>();
            foreach (var match in foundMatches)
            {
                var metricUrl = $"https://betbuilder.digitalsportstech.com/api/feed?betType=in,18,19&gameId={match.SourceId}&limit=9999&sb=topsport&tz=7";
                rawDoc = await ScrapeHelper.GetDocument(metricUrl);

                jDoc = JsonConvert.DeserializeObject <JToken>(rawDoc);
                var rawMetrics = jDoc.SelectTokens("$.data[*]").ToList();

                currentRange = Math.Min(currentRange + rangeProgress, 80);

                foreach (var rawMetric in rawMetrics)
                {
                    var statistic = rawMetric.SelectToken("$.statistic.title").ToString();
                    var scoreType =
                        statistic.Contains("Pts + Reb + Ast") ? ScoreType.PointReboundAssist :
                        statistic.Contains("Total Rebounds") ? ScoreType.Rebound :
                        statistic.Contains("Assists") ? ScoreType.Assist :
                        statistic.Contains("Points") ? ScoreType.Point :
                        statistic.Contains("Three Point") ? ScoreType.ThreePoint :
                        string.Empty;
                    if (string.IsNullOrEmpty(scoreType))
                    {
                        continue;
                    }

                    var playerName = rawMetric.SelectToken("$.player1.name").ToString();
                    var player     = ScrapeHelper.FindPlayerInMatch(playerName, match);
                    if (player == null)
                    {
                        Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                        continue;
                    }

                    var betType = rawMetric.SelectToken("$.betType").ToString();

                    double?over = 0, overLine = 0, under = 0, underLine = 0;
                    switch (betType)
                    {
                    case "18":
                        over     = ScrapeHelper.ConvertMetric(rawMetric.SelectToken("$.markets[0].odds").ToString());
                        overLine = ScrapeHelper.ConvertMetric(rawMetric.SelectToken("$.markets[0].value").ToString());
                        break;

                    case "19":
                        under     = ScrapeHelper.ConvertMetric(rawMetric.SelectToken("$.markets[0].odds").ToString());
                        underLine = ScrapeHelper.ConvertMetric(rawMetric.SelectToken("$.markets[0].value").ToString());
                        break;
                    }

                    var metric = new PlayerOverUnder
                    {
                        MatchId               = match.Id,
                        Over                  = over,
                        OverLine              = overLine,
                        Under                 = under,
                        UnderLine             = underLine,
                        PlayerId              = player.Id,
                        Player                = player,
                        ScoreType             = scoreType,
                        ScrapingInformationId = GetScrapingInformation().Id,
                        CreatedAt             = DateTime.Now
                    };

                    _rawData.Add(metric);

                    var newProgress = GetScrapingInformation().Progress;
                    newProgress = Math.Min(newProgress + currentRange / rawMetrics.Count, currentRange);
                    await UpdateScrapeStatus(newProgress, null);
                }
                await UpdateScrapeStatus(currentRange, null);
            }
            Logger.Information("Scrape metric data complete");

            MergeData();
            Logger.Information("Merge data complete");

            await UpdateScrapeStatus(90, "Scrape metric data complete");
        }
        protected override async Task ScrapeData()
        {
            var chromeDriver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

            try
            {
                const string url = "https://www.5dimes.eu/";
                chromeDriver.Navigate().GoToUrl(url);
                await Task.Delay(2000);

                var userElement = chromeDriver.FindElementById("customerID");
                userElement.SendKeys("5D2543319");
                var passwordElement = chromeDriver.FindElementByName("password");
                passwordElement.SendKeys("qwerty123!");
                var loginButton = chromeDriver.FindElementById("submit1");
                loginButton.Click();
                await Task.Delay(2000);

                var nbaCheckbox = chromeDriver.FindElementByName("Basketball_NBA Props");
                nbaCheckbox.Click();

                var nbaSubmitElement = chromeDriver.FindElementById("btnContinue");
                nbaSubmitElement.Click();

                var doc = new HtmlDocument();
                doc.LoadHtml(chromeDriver.PageSource);

                var rawMatches = doc.DocumentNode.SelectNodes("//html/body/form/div[@id='PageElt']/div/div[@id='Middle']/div[@id='contentRight']/div[@id='ManagedContentWrapper']/div[@id='MainContent']/div[@id='mainContentContainer']/div[@id='readingPaneSplitPane']/div[@id='readingPaneContainer']/div[@id='readingPaneContentContainer']/div[@id='contentContainer']/div[@class='linesContainer']/table/tbody/tr");
                for (var i = 0; i < rawMatches.Count; i++)
                {
                    var tdScoreName = rawMatches[i].SelectSingleNode("td[3]");
                    if (tdScoreName == null)
                    {
                        continue;
                    }
                    var scoreText = tdScoreName.InnerText;
                    var scoreType =
                        scoreText.Contains("points") && !scoreText.Contains("first") && !scoreText.Contains("total") && !scoreText.Contains("wins") ? ScoreType.Point :
                        scoreText.Contains("assists") ? ScoreType.Assist :
                        scoreText.Contains("rebounds") ? ScoreType.Rebound :
                        scoreText.Contains("3-Pt") ? ScoreType.ThreePoint :
                        scoreText.Contains("pts+reb+ast") ? ScoreType.PointReboundAssist :
                        scoreText.Contains("pts+reb") ? ScoreType.PointRebound :
                        scoreText.Contains("pts+ast") ? ScoreType.PointAssist :
                        scoreText.Contains("reb+ast") ? ScoreType.ReboundAssist
                        : string.Empty;
                    if (string.IsNullOrEmpty(scoreType))
                    {
                        continue;
                    }

                    var scoreSplits = scoreText.Split();
                    var playerName  = scoreSplits[1].Replace(".", " ");

                    var match = ScrapeHelper.FindMatchByPlayerName(playerName, TodayMatches);
                    if (match == null)
                    {
                        continue;
                    }
                    var player = ScrapeHelper.FindPlayerInMatch(playerName, match);

                    var overText = rawMatches[i].SelectSingleNode("td[6]").InnerText;
                    var overLine = ScrapeHelper.ConvertMetric($"{ScrapeHelper.RegexMappingExpression(overText, "o(.*)½")}.05");
                    var over     = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(overText, @"½ [\-\+](.*)").Trim());

                    var underText = rawMatches[i + 1].SelectSingleNode("td[6]").InnerText;
                    var underLine = ScrapeHelper.ConvertMetric($"{ScrapeHelper.RegexMappingExpression(underText, "u(.*)½")}.05");
                    var under     = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(underText, @"½ [\-\+](.*)").Trim());

                    Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                    var metric = new PlayerOverUnder
                    {
                        MatchId               = match.Id,
                        Over                  = over,
                        OverLine              = overLine,
                        Under                 = under,
                        UnderLine             = underLine,
                        PlayerId              = player.Id,
                        ScoreType             = scoreType,
                        ScrapingInformationId = GetScrapingInformation().Id,
                        CreatedAt             = DateTime.Now
                    };

                    PlayerUnderOvers.Add(metric);
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString());
                chromeDriver.Quit();
                throw;
            }
            chromeDriver.Quit();
        }
        protected override async Task ScrapeData()
        {
            const string url       = "https://fixture.palmerbet.online/fixtures/sports/1c2eeb3a-6bab-4ac2-b434-165cc350180f/matches?pageSize=25";
            var          rawResult = await ScrapeHelper.GetDocument(url);

            var matchObj = JsonConvert.DeserializeObject <JToken>(rawResult);

            var rawMatches   = matchObj.SelectTokens("$.matches[*]");
            var foundMatches = new List <Match>();

            await UpdateScrapeStatus(10, "Scraping match data");

            foreach (var rawMatch in rawMatches)
            {
                var sourceMatchId = rawMatch.SelectToken("$.eventId").ToString();
                if (string.IsNullOrEmpty(sourceMatchId))
                {
                    Logger.Warning("Source Id is null");
                    continue;
                }

                var homeTeam = rawMatch.SelectToken("$.homeTeam.title").ToString();
                var awayTeam = rawMatch.SelectToken("$.awayTeam.title").ToString();
                var match    = ScrapeHelper.FindMatchByHomeAndAwayTeam(TodayMatches, homeTeam, awayTeam);
                if (match == null)
                {
                    Logger.Warning($"Cannot find match with Home team: {homeTeam} and Away team: {awayTeam}");
                    continue;
                }

                match.SourceId = sourceMatchId;
                foundMatches.Add(match);
            }

            await UpdateScrapeStatus(20, "Scrape match data complete");

            var rawMetricsTasks = foundMatches
                                  .Select(match => $"https://fixture.palmerbet.online/fixtures/sports/matches/{match.SourceId}/markets?pageSize=1000")
                                  .Select(metricUrl => ScrapeHelper.GetDocument(metricUrl))
                                  .ToList();

            var rawMetrics = await Task.WhenAll(rawMetricsTasks);

            await UpdateScrapeStatus(20, "Scraping metric data");

            var rangeProgress = rawMetrics.Length != 0 ? 90 / rawMetrics.Length : 0;
            var currentRange  = 20;

            Logger.Information($"Total raw metrics count {rawMetrics.Length}");
            var totalMetrics = 0;

            try
            {
                for (var i = 0; i < rawMetrics.Length; i++)
                {
                    var rawMetric     = rawMetrics[i];
                    var metricObj     = JsonConvert.DeserializeObject <JToken>(rawMetric);
                    var metricMarkets = metricObj.SelectTokens("$.markets[?(@.title=~ /(.* - .*)/)]").ToList();

                    currentRange = Math.Min(currentRange + rangeProgress, 90);

                    foreach (var metricMarket in metricMarkets)
                    {
                        var title = metricMarket.SelectToken("$.title").ToString();

                        var scoreType =
                            title.Contains("Points") ? ScoreType.Point :
                            title.Contains("Rebounds") ? ScoreType.Rebound :
                            title.Contains("Assists") ? ScoreType.Assist :
                            title.Contains("Made Threes") ? ScoreType.ThreePoint :
                            title.Contains("Pts + Ast") ? ScoreType.PointAssist :
                            title.Contains("Pts + Reb + Ast") ? ScoreType.PointReboundAssist :
                            title.Contains("Pts + Reb") ? ScoreType.PointRebound :
                            title.Contains("Reb + Ast") ? ScoreType.ReboundAssist :
                            string.Empty;

                        if (string.IsNullOrEmpty(scoreType))
                        {
                            continue;
                        }
                        var playerName = title.Split('-')[0].Trim();
                        var player     = ScrapeHelper.FindPlayerInMatch(playerName, foundMatches[i]);
                        if (player == null)
                        {
                            Logger.Warning($"Cannot find any player {playerName} in match {foundMatches[i].Id}");
                            continue;
                        }

                        totalMetrics++;

                        var playerId = metricMarket.SelectToken("$.id").ToString();
                        var priceUrl = $"https://fixture.palmerbet.online/fixtures/sports/markets/{playerId}";
                        var priceDoc = await ScrapeHelper.GetDocument(priceUrl, 3000);

                        var priceObj = JsonConvert.DeserializeObject <JToken>(priceDoc);

                        if (priceObj == null)
                        {
                            Logger.Warning($"priceObj is null for player: {playerId}");
                            continue;
                        }

                        var    outcomeItems = priceObj.SelectTokens("$.market.outcomes[*]");
                        double?over = 0, overLine = 0, under = 0, underLine = 0;
                        foreach (var outcomeItem in outcomeItems)
                        {
                            var titleItem = outcomeItem.SelectToken("$.title").ToString();

                            if (titleItem.Contains("Over"))
                            {
                                var rawOver  = ScrapeHelper.RegexMappingExpression(titleItem, "(?:Over) (.*)");
                                var rawPrice = outcomeItem.SelectTokens("$.prices[*]").FirstOrDefault()
                                               .SelectToken("$.priceSnapshot.current").ToString();

                                overLine = ScrapeHelper.ConvertMetric(rawOver);
                                over     = ScrapeHelper.ConvertMetric(rawPrice);
                            }
                            else if (titleItem.Contains("Under"))
                            {
                                var rawUnder = ScrapeHelper.RegexMappingExpression(titleItem, "(?:Under) (.*)");
                                var rawPrice = outcomeItem.SelectTokens("$.prices[*]").FirstOrDefault()
                                               .SelectToken("$.priceSnapshot.current").ToString();

                                underLine = ScrapeHelper.ConvertMetric(rawUnder);
                                under     = ScrapeHelper.ConvertMetric(rawPrice);
                            }
                        }

                        Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                        var metric = new PlayerOverUnder
                        {
                            PlayerId              = player.Id,
                            ScoreType             = scoreType,
                            ScrapingInformationId = GetScrapingInformation().Id,
                            MatchId   = foundMatches[i].Id,
                            Over      = over,
                            OverLine  = overLine,
                            Under     = under,
                            UnderLine = underLine,
                            CreatedAt = DateTime.Now
                        };

                        PlayerUnderOvers.Add(metric);

                        var newProgress = GetScrapingInformation().Progress;
                        newProgress = Math.Min(newProgress + currentRange / metricMarkets.Count, currentRange);
                        await UpdateScrapeStatus(newProgress, null);
                    }

                    await UpdateScrapeStatus(currentRange, null);
                }
                await UpdateScrapeStatus(90, "Scrape metric data complete");

                Logger.Information($"Total metric count: {totalMetrics}");
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString());
                throw;
            }
        }
Example #9
0
        protected override async Task ScrapeData()
        {
            const string url = "https://api.beta.tab.com.au/v1/tab-info-service/sports/Basketball/competitions/NBA/matches?jurisdiction=VIC";
            var          doc = await ScrapeHelper.GetDocument(url);

            var jDoc       = JsonConvert.DeserializeObject <JToken>(doc);
            var rawMatches = jDoc.SelectTokens("$.matches[*]");

            await UpdateScrapeStatus(10, "Scraping match data");

            Logger.Information("Scraping match data");
            var foundMatches = new List <Match>();

            foreach (var rawMatch in rawMatches)
            {
                var sourceId = rawMatch.SelectToken("$._links.self").ToString();
                if (string.IsNullOrEmpty(sourceId))
                {
                    Logger.Warning("Source match id is null");
                    continue;
                }

                var matchName = rawMatch.SelectToken("$.name").ToString();

                var homeTeam = ScrapeHelper.RegexMappingExpression(matchName, "(.*) v .*");
                var awayTeam = ScrapeHelper.RegexMappingExpression(matchName, ".* v (.*)");

                var match = ScrapeHelper.FindMatchByHomeAndAwayTeam(TodayMatches, homeTeam, awayTeam);
                if (match == null)
                {
                    Logger.Warning($"Cannot find match with Home team: {homeTeam} and Away team: {awayTeam}");
                    continue;
                }

                match.SourceId = sourceId;
                foundMatches.Add(match);
            }
            await UpdateScrapeStatus(20, "Scrape match data complete");

            await UpdateScrapeStatus(20, "Scraping metric data");

            var rangeProgress = foundMatches.Count != 0 ? 90 / foundMatches.Count : 0;
            var currentRange  = 20;

            Logger.Information("Scrape metric data");
            foreach (var match in foundMatches)
            {
                doc = await ScrapeHelper.GetDocument($"{match.SourceId}");

                jDoc = JsonConvert.DeserializeObject <JToken>(doc);
                var rawMetrics = jDoc.SelectTokens("$.markets[?(@.betOptionSpectrumId =~ /(837|838|839|1789|1791)/)]").ToList();

                currentRange = Math.Min(currentRange + rangeProgress, 90);

                foreach (var rawMetric in rawMetrics)
                {
                    var spectrumId = rawMetric.SelectToken("$.betOptionSpectrumId").ToString();
                    var scoreType  = spectrumId == "837" ? ScoreType.Point :
                                     spectrumId == "838" ? ScoreType.Rebound :
                                     spectrumId == "839" ? ScoreType.Assist :
                                     spectrumId == "1789" ? ScoreType.PointReboundAssist :
                                     spectrumId == "1791" ? ScoreType.ThreePoint :
                                     string.Empty;

                    if (string.IsNullOrEmpty(scoreType))
                    {
                        continue;
                    }

                    var playerOvers  = rawMetric.SelectTokens("$.propositions[?(@.name =~ /(.* Over .*)/)]").ToList();
                    var playerUnders = rawMetric.SelectTokens("$.propositions[?(@.name =~ /(.* Under .*)/)]").ToList();

                    var playerNames = new HashSet <string>();
                    foreach (var playerName in playerOvers.Select(item => item.SelectToken("name").ToString()).Select(itemName => ScrapeHelper.RegexMappingExpression(itemName, "(.*)(?:Over|Under)")))
                    {
                        playerNames.Add(playerName);
                    }

                    foreach (var playerName in playerUnders.Select(item => item.SelectToken("name").ToString()).Select(itemName => ScrapeHelper.RegexMappingExpression(itemName, "(.*)(?:Over|Under)")))
                    {
                        playerNames.Add(playerName);
                    }

                    foreach (var playerName in playerNames)
                    {
                        var player = ScrapeHelper.FindPlayerInMatch(playerName, match);
                        if (player == null)
                        {
                            Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                            continue;
                        }
                        var overOutcomeItem = playerOvers.FirstOrDefault(x => x.SelectToken("$.name").ToString().Contains(playerName));
                        var overName        = overOutcomeItem?.SelectToken("name").ToString() ?? string.Empty;
                        var overLine        = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(overName, @".* (\d*.\d*) .*"));
                        var over            = ScrapeHelper.ConvertMetric(overOutcomeItem?.SelectToken("returnWin").ToString() ?? string.Empty);

                        var underOutcomeItem = playerUnders.FirstOrDefault(x => x.SelectToken("$.name").ToString().Contains(playerName));
                        var underName        = underOutcomeItem?.SelectToken("name").ToString() ?? string.Empty;
                        var underLine        = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(underName, @".* (\d*.\d*) .*"));
                        var under            = ScrapeHelper.ConvertMetric(underOutcomeItem?.SelectToken("returnWin").ToString() ?? string.Empty);

                        Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                        var metric = new PlayerOverUnder
                        {
                            MatchId               = match.Id,
                            Over                  = over,
                            OverLine              = overLine,
                            Under                 = under,
                            UnderLine             = underLine,
                            PlayerId              = player.Id,
                            ScoreType             = scoreType,
                            ScrapingInformationId = GetScrapingInformation().Id,
                            CreatedAt             = DateTime.Now
                        };

                        PlayerUnderOvers.Add(metric);
                    }

                    var newProgress = GetScrapingInformation().Progress;
                    newProgress = Math.Min(newProgress + currentRange / rawMetrics.Count, currentRange);
                    await UpdateScrapeStatus(newProgress, null);
                }
                await UpdateScrapeStatus(currentRange, null);
            }
            Logger.Information("Scrape metric data complete");
            await UpdateScrapeStatus(90, "Scrape metric data complete");
        }
Example #10
0
        protected override async Task ScrapeData()
        {
            var chromeDriver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

            try
            {
                const string url = "https://beteasy.com.au/api/sports/sports?filters%5BEventTypes%5D=107&filters%5BMasterCategoryID%5D=37";
                chromeDriver.Navigate().GoToUrl(url);
                await Task.Delay(10000);

                var pageSource = ScrapeHelper.RegexMappingExpression(chromeDriver.PageSource, "({.*})");
                var jDocument  = JsonConvert.DeserializeObject <JToken>(pageSource);
                var rawMatches = jDocument.SelectTokens("$.result.sports.events[*]");

                await UpdateScrapeStatus(10, "Scraping match data");

                Logger.Information("Scraping match data");
                var foundMatches = new List <Match>();
                foreach (var rawMatch in rawMatches)
                {
                    var sourceMatchId = rawMatch.SelectToken("$.MasterEventID").ToString();
                    if (string.IsNullOrEmpty(sourceMatchId))
                    {
                        Logger.Warning("Source match id is null");
                        continue;
                    }

                    var eventName = rawMatch.SelectToken("$.MasterEventName").ToString();
                    if (string.IsNullOrEmpty(eventName))
                    {
                        Logger.Warning("Even name is null");
                        continue;
                    }

                    var homeTeam = eventName.Split('@')[1];
                    var awayTeam = eventName.Split('@')[0];

                    var match = ScrapeHelper.FindMatchByHomeAndAwayTeam(TodayMatches, homeTeam, awayTeam);
                    if (match == null)
                    {
                        Logger.Warning($"Cannot find match with Home team: {homeTeam} and Away team: {awayTeam}");
                        continue;
                    }

                    match.SourceId = sourceMatchId;
                    foundMatches.Add(match);
                }
                await UpdateScrapeStatus(20, "Scrape match data complete");

                Logger.Information("Scrape matches done");

                await UpdateScrapeStatus(20, "Scrape single metrics data");

                var rangeProgress = foundMatches.Count != 0 ? 55 / foundMatches.Count : 0;
                var currentRange  = 20;
                Logger.Information("Scrape single metrics data");
                foreach (var match in foundMatches)
                {
                    var singleMetricUrl =
                        $"https://beteasy.com.au/api/sports/event-group/?id={match.SourceId}&ecGroupOrderByIds%5B%5D=18";

                    chromeDriver.Navigate().GoToUrl(singleMetricUrl);
                    await Task.Delay(5000);

                    currentRange = Math.Min(currentRange + rangeProgress, 55);

                    var metricPageSource = ScrapeHelper.RegexMappingExpression(chromeDriver.PageSource, "({.*})");
                    var jRawMetrics      = JsonConvert.DeserializeObject <JToken>(metricPageSource);
                    var rawMetrics       = jRawMetrics.SelectTokens("$.result.*.BettingType[*]").ToList();

                    foreach (var rawMetric in rawMetrics)
                    {
                        var eventName = rawMetric.SelectToken("$.EventName").ToString();
                        var scoreType =
                            eventName.Contains("Points") ? ScoreType.Point :
                            eventName.Contains("Rebounds") ? ScoreType.Rebound :
                            eventName.Contains("Assists") ? ScoreType.Assist :
                            string.Empty;

                        if (string.IsNullOrEmpty(scoreType))
                        {
                            continue;
                        }

                        var playerName = ScrapeHelper.RegexMappingExpression(eventName, "(.*) (Points|Rebounds|Assists)");
                        var player     = ScrapeHelper.FindPlayerInMatch(playerName, match);
                        if (player == null)
                        {
                            Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                            continue;
                        }

                        var    outcomes = rawMetric.SelectTokens("$.Outcomes[*]");
                        double?over = 0, overLine = 0, under = 0, underLine = 0;
                        foreach (var outcome in outcomes)
                        {
                            var outcomeName = outcome.SelectToken("$.OutcomeName").ToString();
                            if (outcomeName.Contains("Over"))
                            {
                                var rawOver  = ScrapeHelper.RegexMappingExpression(outcomeName, "Over (.*)");
                                var rawPrice = outcome.SelectToken("$.BetTypes[0]").SelectToken("$.Price").ToString();

                                overLine = ScrapeHelper.ConvertMetric(rawOver);
                                over     = ScrapeHelper.ConvertMetric(rawPrice);
                            }
                            else if (outcomeName.Contains("Under"))
                            {
                                var rawUnder = ScrapeHelper.RegexMappingExpression(outcomeName, "Under (.*)");
                                var rawPrice = outcome.SelectToken("$.BetTypes[0]").SelectToken("$.Price").ToString();

                                underLine = ScrapeHelper.ConvertMetric(rawUnder);
                                under     = ScrapeHelper.ConvertMetric(rawPrice);
                            }
                        }
                        Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                        var metric = new PlayerOverUnder
                        {
                            MatchId               = match.Id,
                            Over                  = over,
                            OverLine              = overLine,
                            Under                 = under,
                            UnderLine             = underLine,
                            PlayerId              = player.Id,
                            ScoreType             = scoreType,
                            ScrapingInformationId = GetScrapingInformation().Id,
                            CreatedAt             = DateTime.Now
                        };

                        PlayerUnderOvers.Add(metric);

                        var newProgress = GetScrapingInformation().Progress;
                        newProgress = Math.Min(newProgress + currentRange / rawMetrics.Count, currentRange);
                        await UpdateScrapeStatus(newProgress, null);
                    }
                    await UpdateScrapeStatus(currentRange, null);
                }
                Logger.Information("Scrape single metrics data complete");
                await UpdateScrapeStatus(55, "Scrape single metrics data complete");

                Logger.Information("Scrape combination metrics data");

                rangeProgress = foundMatches.Count != 0 ? 90 / foundMatches.Count : 0;
                currentRange  = 55;
                await UpdateScrapeStatus(55, "Scrape combination metrics data");

                foreach (var match in foundMatches)
                {
                    var combinationMetricUrl =
                        $"https://beteasy.com.au/api/sports/event-group/?id={match.SourceId}&ecGroupOrderByIds%5B%5D=24";

                    chromeDriver.Navigate().GoToUrl(combinationMetricUrl);
                    await Task.Delay(5000);

                    currentRange = Math.Min(currentRange + rangeProgress, 90);

                    var metricPageSource = ScrapeHelper.RegexMappingExpression(chromeDriver.PageSource, "({.*})");
                    var jRawMetrics      = JsonConvert.DeserializeObject <JToken>(metricPageSource);
                    var rawMetrics       = jRawMetrics.SelectTokens("$.result.*.BettingType[*]").ToList();

                    foreach (var rawMetric in rawMetrics)
                    {
                        var eventName = rawMetric.SelectToken("$.EventName").ToString();
                        var scoreType =
                            eventName.Contains("Points + Rebounds + Assists") ? ScoreType.PointReboundAssist :
                            eventName.Contains("Points + Rebounds") ? ScoreType.PointRebound :
                            eventName.Contains("Points + Assists") ? ScoreType.PointAssist :
                            eventName.Contains("Rebounds + Assists") ? ScoreType.ReboundAssist :
                            string.Empty;

                        if (string.IsNullOrEmpty(scoreType))
                        {
                            continue;
                        }
                        var outcomes = rawMetric.SelectTokens("$.Outcomes[*]").ToList();

                        Player player = null;
                        foreach (var outcomeName in outcomes.Select(outcome => outcome.SelectToken("$.OutcomeName").ToString()))
                        {
                            if (outcomeName.Contains("Over"))
                            {
                                var playerName = ScrapeHelper.RegexMappingExpression(outcomeName, "(.*) Over");
                                player = ScrapeHelper.FindPlayerInMatch(playerName, match);
                                if (player != null)
                                {
                                    continue;
                                }
                                Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                            }
                            else if (outcomeName.Contains("Under"))
                            {
                                var playerName = ScrapeHelper.RegexMappingExpression(outcomeName, "(.*) Under");
                                player = ScrapeHelper.FindPlayerInMatch(playerName, match);
                                if (player != null)
                                {
                                    continue;
                                }
                                Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                            }
                        }

                        if (player == null)
                        {
                            continue;
                        }

                        double?over = 0, overLine = 0, under = 0, underLine = 0;
                        foreach (var outcome in outcomes)
                        {
                            var outcomeName = outcome.SelectToken("$.OutcomeName").ToString();
                            if (outcomeName.Contains("Over"))
                            {
                                var rawOver  = ScrapeHelper.RegexMappingExpression(outcomeName, "Over (.*)");
                                var rawPrice = outcome.SelectToken("$.BetTypes[0]").SelectToken("$.Price").ToString();

                                overLine = string.IsNullOrEmpty(rawOver) ? (double?)null : Convert.ToDouble(rawOver);
                                over     = string.IsNullOrEmpty(rawPrice) ? (double?)null : Convert.ToDouble(rawPrice);
                            }
                            else if (outcomeName.Contains("Under"))
                            {
                                var rawUnder = ScrapeHelper.RegexMappingExpression(outcomeName, "Under (.*)");
                                var rawPrice = outcome.SelectToken("$.BetTypes[0]").SelectToken("$.Price").ToString();

                                underLine = string.IsNullOrEmpty(rawUnder) ? (double?)null : Convert.ToDouble(rawUnder);
                                under     = string.IsNullOrEmpty(rawPrice) ? (double?)null : Convert.ToDouble(rawPrice);
                            }
                        }
                        Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                        var metric = new PlayerOverUnder
                        {
                            MatchId               = match.Id,
                            Over                  = over,
                            OverLine              = overLine,
                            Under                 = under,
                            UnderLine             = underLine,
                            PlayerId              = player.Id,
                            ScoreType             = scoreType,
                            ScrapingInformationId = GetScrapingInformation().Id,
                            CreatedAt             = DateTime.Now
                        };

                        PlayerUnderOvers.Add(metric);

                        var newProgress = GetScrapingInformation().Progress;
                        newProgress = Math.Min(newProgress + currentRange / rawMetrics.Count, currentRange);
                        await UpdateScrapeStatus(newProgress, null);
                    }
                    await UpdateScrapeStatus(currentRange, null);
                }
                Logger.Information("Scrape combination metrics data complete");
                await UpdateScrapeStatus(90, "Scrape combination metrics data complete");
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString());
                chromeDriver.Quit();
                throw;
            }
            chromeDriver.Quit();
        }
Example #11
0
        protected override async Task ScrapeData()
        {
            var chromeDriver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

            try
            {
                const string url = "https://nodejs08.tglab.io/cache/20/en/us/11624/prematch-by-tournaments.json";
                chromeDriver.Navigate().GoToUrl(url);
                await Task.Delay(2000);

                var pageSource = ScrapeHelper.RegexMappingExpression(chromeDriver.PageSource, "({.*})");
                var jDocument  = JsonConvert.DeserializeObject <JToken>(pageSource);
                var rawMatches = jDocument.SelectTokens("$.events[*]");

                var foundMatches = new List <Match>();
                foreach (var rawMatch in rawMatches)
                {
                    var sourceId = rawMatch.SelectToken("$.id").ToString();
                    if (string.IsNullOrEmpty(sourceId))
                    {
                        Logger.Warning("Source match id is null");
                        continue;
                    }

                    var homeTeam = rawMatch.SelectToken("$.teams.home").ToString();
                    var awayTeam = rawMatch.SelectToken("$.teams.away").ToString();

                    var match = ScrapeHelper.FindMatchByHomeAndAwayTeam(TodayMatches, homeTeam, awayTeam);
                    if (match == null)
                    {
                        Logger.Warning($"Cannot find match with Home team: {homeTeam} and Away team: {awayTeam}");
                        continue;
                    }

                    match.SourceId = sourceId;
                    foundMatches.Add(match);
                }

                var tempMetrics = new List <PlayerOverUnder>();
                foreach (var match in foundMatches)
                {
                    var metricUrl = $"https://nodejs08.tglab.io/cache/20/en/us/{match.SourceId}/single-pre-event.json?hidenseek=95183b1a46914705952f351b5bc156fd8e1e7b57be65d492e09186129ff70e8a1ba8";
                    chromeDriver.Navigate().GoToUrl(metricUrl);
                    await Task.Delay(2000);

                    var pageSourceMarket = ScrapeHelper.RegexMappingExpression(chromeDriver.PageSource, "({.*})");
                    var marketData       = JsonConvert.DeserializeObject <JToken>(pageSourceMarket);

                    var rawMetrics = marketData.SelectTokens("$.odds.*");
                    foreach (var rawMetric in rawMetrics)
                    {
                        var teamName = rawMetric.SelectToken("$.team_name.en").ToString();
                        if (!teamName.Contains("total points"))
                        {
                            continue;
                        }

                        var playerSplits = ScrapeHelper.RegexMappingExpression(teamName, "(.*) total").Split('.');
                        var playerName   = $"{playerSplits[0]} {playerSplits[1]}";
                        var player       = ScrapeHelper.FindPlayerInMatch(playerName, match);
                        if (player == null)
                        {
                            Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                            continue;
                        }

                        var metric = tempMetrics.FirstOrDefault(x => x.PlayerId == player.Id);
                        if (teamName.Contains("OVER"))
                        {
                            if (metric != null)
                            {
                                metric.OverLine = ScrapeHelper.ConvertMetric(rawMetric.SelectToken("$.additional_value_raw").ToString());
                                metric.Over     = ScrapeHelper.ConvertMetric(rawMetric.SelectToken("$.odd_value").ToString());
                            }
                            else
                            {
                                var newMetric = new PlayerOverUnder
                                {
                                    MatchId  = match.Id,
                                    PlayerId = player.Id,
                                    OverLine = ScrapeHelper.ConvertMetric(rawMetric.SelectToken("$.additional_value_raw").ToString()),
                                    Over     = ScrapeHelper.ConvertMetric(rawMetric.SelectToken("$.odd_value").ToString()),
                                    ScrapingInformationId = GetScrapingInformation().Id,
                                    CreatedAt             = DateTime.Now
                                };
                                tempMetrics.Add(newMetric);
                            }
                        }
                        else if (teamName.Contains("UNDER"))
                        {
                            if (metric != null)
                            {
                                metric.UnderLine = ScrapeHelper.ConvertMetric(rawMetric.SelectToken("$.additional_value_raw").ToString());
                                metric.Under     = ScrapeHelper.ConvertMetric(rawMetric.SelectToken("$.odd_value").ToString());
                            }
                            else
                            {
                                var newMetric = new PlayerOverUnder
                                {
                                    MatchId               = match.Id,
                                    PlayerId              = player.Id,
                                    UnderLine             = ScrapeHelper.ConvertMetric(rawMetric.SelectToken("$.additional_value_raw").ToString()),
                                    Under                 = ScrapeHelper.ConvertMetric(rawMetric.SelectToken("$.odd_value").ToString()),
                                    ScrapingInformationId = GetScrapingInformation().Id,
                                    CreatedAt             = DateTime.Now
                                };
                                tempMetrics.Add(newMetric);
                            }
                        }
                    }
                }

                foreach (var metric in tempMetrics)
                {
                    Logger.Information($"{metric.Player.Name}: " +
                                       $"{metric.Over} {metric.OverLine} | " +
                                       $"{metric.Under} {metric.UnderLine}");
                }

                PlayerUnderOvers.AddRange(tempMetrics);
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString());
                chromeDriver.Quit();
                throw;
            }
            chromeDriver.Quit();
        }
Example #12
0
        protected override async Task ScrapeData()
        {
            var chromeDriver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

            try
            {
                const string url = "https://nj.betamerica.com/sports/basketball/nba/";
                chromeDriver.Navigate().GoToUrl(url);
                await Task.Delay(20000);

                var doc = new HtmlDocument();
                doc.LoadHtml(chromeDriver.PageSource);
                var rawMatches = doc.DocumentNode.SelectNodes("/html/body/div[4]/div/div[2]/div/section[7]/div[2]/div[2]/div/sb-comp/div[1]/div/sb-lazy-render/div[*]");

                var sourceIds = rawMatches
                                .Select(rawMatch => rawMatch.SelectSingleNode("div/a"))
                                .Select(aTag => aTag.GetAttributeValue("href", string.Empty))
                                .Where(sourceId => !sourceId.Contains("live-betting")).ToList();

                await UpdateScrapeStatus(10, "Scraping metric data");

                var rangeProgress = sourceIds.Count != 0 ? 90 / sourceIds.Count : 0;
                var currentRange  = 10;
                foreach (var matchUrl in sourceIds.Select(sourceId => $"https://nj.betamerica.com{sourceId}"))
                {
                    chromeDriver.Navigate().GoToUrl(matchUrl);
                    await Task.Delay(7000);

                    doc.LoadHtml(chromeDriver.PageSource);

                    currentRange = Math.Min(currentRange + rangeProgress, 90);

                    var rawMetrics = doc.DocumentNode.SelectNodes("//html/body/div[@class='content-main']/div[contains(@class, 'content-main-inner')]/div[@id='pagesWrapper']/div[@id='panel-center-inner']/section[@id='pre-live-betting']/div/div[@class='event-view-views-switcher']/div/ul");
                    foreach (var rawMetric in rawMetrics)
                    {
                        var liTags = rawMetric.SelectNodes("li");
                        foreach (var liTag in liTags)
                        {
                            var spanItem = liTag.SelectSingleNode("h4/span[2]/span");
                            var spanText = spanItem.InnerText;

                            var scoreType =
                                spanText.Contains("Total Points") ? ScoreType.Point :
                                spanText.Contains("Total Rebounds") ? ScoreType.Rebound :
                                spanText.Contains("Total Assists") ? ScoreType.Assist :
                                spanText.Contains("Pts, Rebs, Asts") ? ScoreType.PointReboundAssist :
                                string.Empty;

                            if (string.IsNullOrEmpty(scoreType))
                            {
                                continue;
                            }

                            var playerName = ScrapeHelper.RegexMappingExpression(spanText, @"(.*) (Total|\(Pts,)");
                            var match      = ScrapeHelper.FindMatchByPlayerName(playerName, TodayMatches);
                            if (match == null)
                            {
                                continue;
                            }

                            var player = ScrapeHelper.FindPlayerInMatch(playerName, match);

                            if (player == null)
                            {
                                Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                                continue;
                            }

                            var overUnderFirstData  = liTag.SelectSingleNode("div/div/div[2]/button");
                            var overUnderSecondData = liTag.SelectSingleNode("div/div/div[1]/button");

                            double?over = 0, overLine = 0, under = 0, underLine = 0;

                            var overUnderFirstLine = overUnderFirstData.SelectSingleNode("span[1]/span[1]").InnerText;
                            if (overUnderFirstLine.Contains("Over"))
                            {
                                overLine = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(overUnderFirstLine, @"Over (\d*.\d*) .*"));
                                var overPriceData = overUnderFirstData.SelectSingleNode("span[2]/span").InnerText;
                                var priceNumber   = ScrapeHelper.ConvertMetric(overPriceData);
                                over = priceNumber != null
                                    ? priceNumber > 0 ? Math.Round((double)(priceNumber / 100 + 1), 2) :
                                       Math.Round((double)(100 / (priceNumber * -1) + 1), 2)
                                    : (double?)null;
                            }
                            else
                            {
                                underLine = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(overUnderFirstLine, @"Under (\d*.\d*) .*"));
                                var underPriceData = overUnderFirstData.SelectSingleNode("span[2]/span").InnerText;
                                var priceNumber    = ScrapeHelper.ConvertMetric(underPriceData);
                                under = priceNumber != null
                                    ? priceNumber > 0 ? Math.Round((double)(priceNumber / 100 + 1), 2) :
                                        Math.Round((double)(100 / (priceNumber * -1) + 1), 2)
                                    : (double?)null;
                            }

                            var overUnderSecondLine = overUnderSecondData.SelectSingleNode("span[1]/span[1]").InnerText;

                            if (overUnderSecondLine.Contains("Over"))
                            {
                                overLine = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(overUnderSecondLine, @"Over (\d*.\d*) .*"));
                                var overPriceData = overUnderSecondData.SelectSingleNode("span[2]/span").InnerText;
                                var priceNumber   = ScrapeHelper.ConvertMetric(overPriceData);
                                over = priceNumber != null
                                    ? priceNumber > 0 ? Math.Round((double)(priceNumber / 100 + 1), 2) :
                                       Math.Round((double)(100 / (priceNumber * -1) + 1), 2)
                                    : (double?)null;
                            }
                            else
                            {
                                underLine = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(overUnderSecondLine, @"Under (\d*.\d*) .*"));
                                var underPriceData = overUnderSecondData.SelectSingleNode("span[2]/span").InnerText;
                                var priceNumber    = ScrapeHelper.ConvertMetric(underPriceData);
                                under = priceNumber != null
                                    ? priceNumber > 0 ? Math.Round((double)(priceNumber / 100 + 1), 2) :
                                        Math.Round((double)(100 / (priceNumber * -1) + 1), 2)
                                    : (double?)null;
                            }

                            Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                            var metric = new PlayerOverUnder
                            {
                                MatchId               = match.Id,
                                Over                  = over,
                                OverLine              = overLine,
                                Under                 = under,
                                UnderLine             = underLine,
                                PlayerId              = player.Id,
                                ScoreType             = scoreType,
                                ScrapingInformationId = GetScrapingInformation().Id,
                                CreatedAt             = DateTime.Now
                            };

                            PlayerUnderOvers.Add(metric);
                        }

                        var newProgress = GetScrapingInformation().Progress;
                        newProgress = Math.Min(newProgress + currentRange / rawMetrics.Count, currentRange);
                        await UpdateScrapeStatus(newProgress, null);
                    }
                    await UpdateScrapeStatus(currentRange, null);
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString());
                chromeDriver.Quit();
                throw;
            }
            chromeDriver.Quit();
        }
        protected override async Task ScrapeData()
        {
            const string url = "https://api.beta.tab.com.au/v1/tab-info-service/sports/Basketball/competitions/NBA/matches?jurisdiction=VIC";
            var          doc = await ScrapeHelper.GetDocument(url);

            var jDoc = JsonConvert.DeserializeObject <JToken>(doc);

            var rawMatches   = jDoc.SelectTokens("$.matches[*]");
            var foundMatches = new List <Match>();

            await UpdateScrapeStatus(10, "Scraping match data");

            Logger.Information("Scraping match data");
            foreach (var rawMatch in rawMatches)
            {
                var sourceMatchId = rawMatch.SelectToken("$._links.self").ToString();
                if (string.IsNullOrEmpty(sourceMatchId))
                {
                    Logger.Warning("Source Id is null");
                    continue;
                }

                var homeTeam = rawMatch.SelectTokens("$.contestants[?(@.position == 'HOME')].name")?.FirstOrDefault()?.ToString();
                var awayTeam = rawMatch.SelectTokens("$.contestants[?(@.position == 'AWAY')].name")?.FirstOrDefault()?.ToString();

                var match = ScrapeHelper.FindMatchByHomeAndAwayTeam(TodayMatches, homeTeam, awayTeam);
                if (match == null)
                {
                    Logger.Warning($"Cannot find match with Home team: {homeTeam} and Away team: {awayTeam}");
                    continue;
                }

                match.SourceId = sourceMatchId;
                foundMatches.Add(match);
            }
            Logger.Information("Scrape match data complete");
            await UpdateScrapeStatus(20, "Scrape match data complete");

            await UpdateScrapeStatus(20, "Scraping metric data");

            var rangeProgress = foundMatches.Count != 0 ? 90 / foundMatches.Count : 0;
            var currentRange  = 20;

            Logger.Information("Scraping metric data");
            foreach (var match in foundMatches)
            {
                doc = await ScrapeHelper.GetDocument(match.SourceId);

                jDoc = JsonConvert.DeserializeObject <JToken>(doc);
                var rawMetrics = jDoc.SelectTokens("$.markets[?(@.betOptionSpectrumId =~ /(605)/)]").ToList();

                currentRange = Math.Min(currentRange + rangeProgress, 90);

                foreach (var rawMetric in rawMetrics)
                {
                    var propositionPlayerA = rawMetric.SelectToken("$.propositions[0]");
                    var propositionTie     = rawMetric.SelectToken("$.propositions[1]");
                    var propositionPlayerB = rawMetric.SelectToken("$.propositions[2]");

                    var playerNameA = ScrapeHelper.RegexMappingExpression(propositionPlayerA.SelectToken("$.name").ToString(), @"(.*)\(");
                    var playerNameB = ScrapeHelper.RegexMappingExpression(propositionPlayerB.SelectToken("$.name").ToString(), @"(.*)\(");
                    var playerA     = ScrapeHelper.FindPlayerInMatch(playerNameA, match);
                    if (playerA == null)
                    {
                        Logger.Warning($"Cannot find any playerA {playerNameA} in match {match.Id}");
                        continue;
                    }

                    var playerB = ScrapeHelper.FindPlayerInMatch(playerNameB, match);
                    if (playerB == null)
                    {
                        Logger.Warning($"Cannot find any playerB {playerNameB} in match {match.Id}");
                        continue;
                    }

                    var priceA   = ScrapeHelper.ConvertMetric(propositionPlayerA.SelectToken("$.returnWin").ToString());
                    var tiePrice = ScrapeHelper.ConvertMetric(propositionTie.SelectToken("$.returnWin").ToString());
                    var priceB   = ScrapeHelper.ConvertMetric(propositionPlayerB.SelectToken("$.returnWin").ToString());

                    Logger.Information($"{playerA.Name} vs {playerB.Name}: {priceA} vs {priceB} | Tie: {tiePrice}");
                    var metric = new PlayerHeadToHead
                    {
                        PlayerAId             = playerA.Id,
                        PlayerBId             = playerB.Id,
                        IsTieIncluded         = tiePrice != null,
                        PlayerAPrice          = priceA,
                        PlayerBPrice          = priceB,
                        ScrapingInformationId = GetScrapingInformation().Id,
                        TiePrice  = tiePrice,
                        MatchId   = match.Id,
                        CreatedAt = DateTime.Now
                    };

                    PlayerHeadToHeads.Add(metric);

                    var newProgress = GetScrapingInformation().Progress;
                    newProgress = Math.Min(newProgress + currentRange / rawMetrics.Count, currentRange);
                    await UpdateScrapeStatus(newProgress, null);
                }
                await UpdateScrapeStatus(currentRange, null);
            }
            Logger.Information("Scrape metric data complete");
            await UpdateScrapeStatus(90, "Scrape metric data complete");
        }
        protected override async Task ScrapeData()
        {
            var chromeDriver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

            try
            {
                const string url = "https://www.betus.com.pa/sportsbook/nba-basketball-lines.aspx";
                chromeDriver.Navigate().GoToUrl(url);
                await Task.Delay(5000);

                var matchCount = chromeDriver.FindElementsByClassName("props").Count;
                await UpdateScrapeStatus(10, "Scraping metric data");

                var rangeProgress = matchCount != 0 ? 90 / matchCount : 0;
                var currentRange  = 10;
                for (var i = 0; i < matchCount; i++)
                {
                    chromeDriver.Navigate().GoToUrl(url);
                    await Task.Delay(3000);

                    var props = chromeDriver.FindElementsByClassName("props");
                    props[i].Click();
                    await Task.Delay(3000);

                    var select = new SelectElement(chromeDriver.FindElementByClassName("odds-display"));
                    select.SelectByText("Decimal");
                    await Task.Delay(2000);

                    var doc = new HtmlDocument();
                    doc.LoadHtml(chromeDriver.PageSource);

                    currentRange = Math.Min(currentRange + rangeProgress, 90);

                    var matchNode  = doc.DocumentNode.SelectSingleNode("//html/body/form/div[@class='sportsbook-visitor']/div[@class='sportsbook-master']/div[@class='rounded-block-white']/span[2]/div[@class='col']/div[@id='game-lines']/div/div[@class='game-block']/div[@class='normal']/div/div[@class='future-lines inline-prop']");
                    var rawMetrics = matchNode.SelectNodes("table");

                    foreach (var rawMetric in rawMetrics)
                    {
                        var playerNode = rawMetric.SelectSingleNode("tbody/tr[1]/th[2]").InnerText;
                        var scoreType  =
                            playerNode.Contains("Total Points+Rebounds+Assists") ? ScoreType.PointReboundAssist :
                            playerNode.Contains("Total Points+Rebounds") ? ScoreType.PointRebound :
                            playerNode.Contains("Total Points+Assists") ? ScoreType.PointAssist :
                            playerNode.Contains("Total Rebounds+Assists") ? ScoreType.ReboundAssist :
                            playerNode.Contains("Total Points") ? ScoreType.Point :
                            playerNode.Contains("Total Rebounds") ? ScoreType.Rebound :
                            playerNode.Contains("Total Assists") ? ScoreType.Assist :
                            playerNode.Contains("Total Made 3") ? ScoreType.ThreePoint :
                            string.Empty;

                        if (string.IsNullOrEmpty(scoreType))
                        {
                            continue;
                        }

                        playerNode = playerNode
                                     .Replace("\n", string.Empty)
                                     .Replace("\r", string.Empty)
                                     .Replace("\t", string.Empty)
                                     .Trim();
                        var playerName = ScrapeHelper.RegexMappingExpression(playerNode, @"(.*) \(");
                        var match      = ScrapeHelper.FindMatchByPlayerName(playerName, TodayMatches);
                        if (match == null)
                        {
                            continue;
                        }

                        var player = ScrapeHelper.FindPlayerInMatch(playerName, match);

                        var overNode = rawMetric.SelectSingleNode("tbody/tr[2]/td[2]").InnerText;
                        overNode = overNode
                                   .Replace("\n", string.Empty)
                                   .Replace("\r", string.Empty)
                                   .Replace("\t", string.Empty)
                                   .Replace("&nbsp;", " ")
                                   .Trim();
                        var overLine = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(overNode, @"Over.(\d*.\d*)"));

                        var overPriceNode = rawMetric.SelectSingleNode("tbody/tr[2]/td[3]/a").InnerText;
                        var over          = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(overPriceNode, @"(\d*.\d*).*"));

                        var underNode = rawMetric.SelectSingleNode("tbody/tr[3]/td[2]").InnerText;
                        underNode = underNode
                                    .Replace("\n", string.Empty)
                                    .Replace("\r", string.Empty)
                                    .Replace("&nbsp;", " ")
                                    .Replace("\t", string.Empty)
                                    .Trim();
                        var underLine      = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(underNode, @"Under.(\d*.\d*)"));
                        var underPriceNode = rawMetric.SelectSingleNode("tbody/tr[3]/td[3]/a").InnerText;
                        var under          = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(underPriceNode, @"(\d*.\d*).*"));

                        Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                        var metric = new PlayerOverUnder
                        {
                            MatchId               = match.Id,
                            Over                  = over,
                            OverLine              = overLine,
                            Under                 = under,
                            UnderLine             = underLine,
                            PlayerId              = player.Id,
                            ScoreType             = scoreType,
                            ScrapingInformationId = GetScrapingInformation().Id,
                            CreatedAt             = DateTime.Now
                        };

                        PlayerUnderOvers.Add(metric);

                        var newProgress = GetScrapingInformation().Progress;
                        newProgress = Math.Min(newProgress + currentRange / rawMetrics.Count, currentRange);
                        await UpdateScrapeStatus(newProgress, null);
                    }
                    await UpdateScrapeStatus(currentRange, null);
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString());
                chromeDriver.Quit();
                throw;
            }
            chromeDriver.Quit();
        }
Example #15
0
        private void ProcessMetric(Match match, IReadOnlyCollection <JToken> entrants,
                                   IReadOnlyCollection <JToken> prices, string scoreType, string actualScoreType)
        {
            var overMetrics = entrants.Where(x =>
            {
                var name = x.Children().FirstOrDefault()?.SelectToken("$.name").ToString();

                if (scoreType == "PR" || scoreType == "RA")
                {
                    return(name != null && name.Contains(actualScoreType) && name.Contains("Over") && !name.Contains("PRA"));
                }
                return(name != null && name.Contains(actualScoreType) && name.Contains("Over"));
            }).ToList();

            var underMetrics = entrants.Where(x =>
            {
                var name = x.Children().FirstOrDefault()?.SelectToken("$.name").ToString();
                if (scoreType == "PR" || scoreType == "RA")
                {
                    return(name != null && name.Contains(actualScoreType) && name.Contains("Under") && !name.Contains("PRA"));
                }
                return(name != null && name.Contains(actualScoreType) && name.Contains("Under"));
            }).ToList();

            var playerNames = new HashSet <string>();

            foreach (var content in overMetrics
                     .Select(overMetric => overMetric
                             .Children()
                             .FirstOrDefault()?
                             .SelectToken("$.name").ToString() ?? string.Empty))
            {
                playerNames.Add(ScrapeHelper.RegexMappingExpression(content, "(.*) Over"));
            }

            foreach (var content in underMetrics
                     .Select(underMetric => underMetric.Children()
                             .FirstOrDefault()?
                             .SelectToken("$.name").ToString() ?? string.Empty))
            {
                playerNames.Add(ScrapeHelper.RegexMappingExpression(content, "(.*) Under"));
            }

            foreach (var playerName in playerNames)
            {
                var player = ScrapeHelper.FindPlayerInMatch(playerName, match);
                if (player == null)
                {
                    Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                    continue;
                }

                var overContent = overMetrics.FirstOrDefault(x =>
                                                             x.Children().FirstOrDefault()?.SelectToken("$.name").ToString().Contains(playerName) ?? false)
                                  ?.Children().FirstOrDefault();

                var underContent = underMetrics.FirstOrDefault(x =>
                                                               x.Children().FirstOrDefault()?.SelectToken("$.name").ToString().Contains(playerName) ?? false)
                                   ?.Children().FirstOrDefault();

                var overLine =
                    ScrapeHelper.ConvertMetric(ScrapeHelper
                                               .RegexMappingExpression(overContent?.SelectToken("$.name").ToString(), "Over (.*) .*"));

                var underLine =
                    ScrapeHelper.ConvertMetric(ScrapeHelper
                                               .RegexMappingExpression(underContent?.SelectToken("$.name").ToString(), "Under (.*) .*"));

                var priceOverId  = overContent?.SelectToken("$.id").ToString() ?? string.Empty;
                var priceUnderId = underContent?.SelectToken("$.id").ToString() ?? string.Empty;

                var priceOverData    = prices.FirstOrDefault(x => x.ToString().Contains(priceOverId));
                var priceOverContent = priceOverData?.Children().FirstOrDefault();
                var numeratorOver    = ScrapeHelper.ConvertMetric(priceOverContent?.SelectToken("$.odds.numerator").ToString());
                var denominatorOver  = ScrapeHelper.ConvertMetric(priceOverContent?.SelectToken("$.odds.denominator").ToString());
                var over             = numeratorOver != null && denominatorOver != null ? numeratorOver / denominatorOver + 1 : null;

                var priceUnderData    = prices.FirstOrDefault(x => x.ToString().Contains(priceUnderId));
                var priceUnderContent = priceUnderData?.Children().FirstOrDefault();
                var numeratorUnder    = ScrapeHelper.ConvertMetric(priceUnderContent.SelectToken("$.odds.numerator").ToString());
                var denominatorUnder  = ScrapeHelper.ConvertMetric(priceUnderContent.SelectToken("$.odds.denominator").ToString());
                var under             = numeratorUnder != null && denominatorUnder != null ? numeratorUnder / denominatorUnder + 1 : null;

                Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                var metric = new PlayerOverUnder
                {
                    MatchId               = match.Id,
                    Over                  = over,
                    OverLine              = overLine,
                    Under                 = under,
                    UnderLine             = underLine,
                    PlayerId              = player.Id,
                    ScoreType             = scoreType,
                    ScrapingInformationId = GetScrapingInformation().Id,
                    CreatedAt             = DateTime.Now
                };

                PlayerUnderOvers.Add(metric);
            }
        }
        protected override async Task ScrapeData()
        {
            const string url    = "https://www.sportsbet.com.au/apigw/sportsbook-sports/Sportsbook/Sports/Competitions/6927/Events";
            var          rawDoc = await ScrapeHelper.GetDocument(url);

            var jDoc = JsonConvert.DeserializeObject <JToken>(rawDoc);

            var rawMatches   = jDoc.SelectTokens("$.[*]");
            var foundMatches = new List <Match>();

            await UpdateScrapeStatus(10, "Scraping match data");

            Logger.Information("Scraping match data");
            foreach (var rawMatch in rawMatches)
            {
                if (rawMatch.SelectToken("$.competitionName").ToString() != "NBA Matches")
                {
                    continue;
                }

                var sourceMatchId = rawMatch.SelectToken("$.id").ToString();
                if (string.IsNullOrEmpty(sourceMatchId))
                {
                    Logger.Warning("Source Id is null");
                    continue;
                }

                var matchName = rawMatch.SelectToken("$.name").ToString();
                var teams     = matchName.Split(new[] { " At " }, StringSplitOptions.None);
                var homeTeam  = teams[1];
                var awayTeam  = teams[0];

                var match = ScrapeHelper.FindMatchByHomeAndAwayTeam(TodayMatches, homeTeam, awayTeam);
                if (match == null)
                {
                    Logger.Warning($"Cannot find match with Home team: {homeTeam} and Away team: {awayTeam}");
                    continue;
                }

                match.SourceId = sourceMatchId;
                foundMatches.Add(match);
            }
            Logger.Information("Scrape match data complete");
            await UpdateScrapeStatus(20, "Scrape match data complete");

            await UpdateScrapeStatus(20, "Scraping metric data");

            var rangeProgress = foundMatches.Count != 0 ? 90 / foundMatches.Count : 0;
            var currentRange  = 20;

            Logger.Information("Scrape metric data");
            foreach (var match in foundMatches)
            {
                var pointsUrl      = $"https://www.sportsbet.com.au/apigw/sportsbook-sports/Sportsbook/Sports/Events/{match.SourceId}/MarketGroupings/567/Markets";
                var reboundsUrl    = $"https://www.sportsbet.com.au/apigw/sportsbook-sports/Sportsbook/Sports/Events/{match.SourceId}/MarketGroupings/568/Markets";
                var assistsUrl     = $"https://www.sportsbet.com.au/apigw/sportsbook-sports/Sportsbook/Sports/Events/{match.SourceId}/MarketGroupings/569/Markets";
                var combinationUrl = $"https://www.sportsbet.com.au/apigw/sportsbook-sports/Sportsbook/Sports/Events/{match.SourceId}/MarketGroupings/570/Markets";

                currentRange = Math.Min(currentRange + rangeProgress, 90);

                var docTasks = new List <Task <string> >
                {
                    ScrapeHelper.GetDocument(pointsUrl),
                    ScrapeHelper.GetDocument(reboundsUrl),
                    ScrapeHelper.GetDocument(assistsUrl),
                    ScrapeHelper.GetDocument(combinationUrl)
                };

                var results = await Task.WhenAll(docTasks);

                var rawMetrics = new List <JToken>();
                foreach (var result in results)
                {
                    rawMetrics.AddRange(JsonConvert.DeserializeObject <JToken>(result).SelectTokens("$.[*]"));
                }

                foreach (var rawMetric in rawMetrics)
                {
                    var metricName = rawMetric.SelectToken("$.name").ToString();
                    var scoreType  =
                        metricName.Contains("Pts + Reb + Ast") ? ScoreType.PointReboundAssist :
                        metricName.Contains("Points") ? ScoreType.Point :
                        metricName.Contains("Assists") ? ScoreType.Assist :
                        metricName.Contains("Made Threes") ? ScoreType.ThreePoint :
                        metricName.Contains("Rebounds") ? ScoreType.Rebound :
                        metricName.Contains("Pts + Reb") ? ScoreType.PointRebound :
                        metricName.Contains("Pts + Ast") ? ScoreType.PointAssist :
                        metricName.Contains("Reb + Ast") ? ScoreType.ReboundAssist :
                        string.Empty;

                    if (string.IsNullOrEmpty(scoreType))
                    {
                        continue;
                    }

                    var playerName = metricName.Split('-')[0];
                    var player     = ScrapeHelper.FindPlayerInMatch(playerName, match);
                    if (player == null)
                    {
                        Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                        continue;
                    }

                    var    selection = rawMetric.SelectToken("$.selections[0]");
                    var    selectionName = selection.SelectToken("$.name").ToString();
                    double?over = 0, overLine = 0, under = 0, underLine = 0;
                    if (selectionName.Contains("Over"))
                    {
                        over     = ScrapeHelper.ConvertMetric(selection.SelectToken("$.price.winPrice")?.ToString());
                        overLine = ScrapeHelper.ConvertMetric(selection.SelectToken("$.unformattedHandicap")?.ToString());
                    }
                    else if (selectionName.Contains("Under"))
                    {
                        under     = ScrapeHelper.ConvertMetric(selection.SelectToken("$.price.winPrice")?.ToString());
                        underLine = ScrapeHelper.ConvertMetric(selection.SelectToken("$.unformattedHandicap")?.ToString());
                    }

                    Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                    var metric = new PlayerOverUnder
                    {
                        PlayerId              = player.Id,
                        ScoreType             = scoreType,
                        ScrapingInformationId = GetScrapingInformation().Id,
                        MatchId   = match.Id,
                        Over      = over,
                        OverLine  = overLine,
                        Under     = under,
                        UnderLine = underLine,
                        CreatedAt = DateTime.Now
                    };

                    PlayerUnderOvers.Add(metric);

                    var newProgress = GetScrapingInformation().Progress;
                    newProgress = Math.Min(newProgress + currentRange / rawMetrics.Count, currentRange);
                    await UpdateScrapeStatus(newProgress, null);
                }
                await UpdateScrapeStatus(currentRange, null);
            }
            Logger.Information("Scrape metric data complete");
            await UpdateScrapeStatus(90, "Scrape metric data complete");
        }
Example #17
0
        protected override async Task ScrapeData()
        {
            const string url = "https://ubet.com/api/sportsViewData/mainevents/false/6698";
            var          doc = await ScrapeHelper.GetDocument(url);

            var jDoc = JsonConvert.DeserializeObject <JToken>(doc);

            var rawMatches   = jDoc.SelectTokens("$.[*]");
            var foundMatches = new List <Match>();

            await UpdateScrapeStatus(10, "Scraping match data");

            Logger.Information("Scraping match data");
            foreach (var rawMatch in rawMatches)
            {
                var sourceMatchId = rawMatch.SelectToken("$.MainEventId").ToString();
                if (string.IsNullOrEmpty(sourceMatchId))
                {
                    Logger.Warning("Source Id is null");
                    continue;
                }

                var mainEventName = rawMatch.SelectToken("$.MainEventName").ToString();
                var date          = Helper.GetCurrentDate("dd/M");
                var teams         = mainEventName
                                    .Split(new[] { date }, StringSplitOptions.None)[0]
                                    .Split(new[] { " v " }, StringSplitOptions.None);

                var homeTeam = teams[0];
                var awayTeam = teams[1];

                var match = ScrapeHelper.FindMatchByHomeAndAwayTeam(TodayMatches, homeTeam, awayTeam);
                if (match == null)
                {
                    Logger.Warning($"Cannot find match with Home team: {homeTeam} and Away team: {awayTeam}");
                    continue;
                }

                match.SourceId = sourceMatchId;
                foundMatches.Add(match);
            }
            Logger.Information("Scrape match data complete");
            await UpdateScrapeStatus(20, "Scrape match data complete");

            await UpdateScrapeStatus(20, "Scraping metric data");

            var rangeProgress = foundMatches.Count != 0 ? 90 / foundMatches.Count : 0;
            var currentRange  = 20;

            Logger.Information("Scraping metric data");
            var betTypes = new HashSet <string>();

            foreach (var match in foundMatches)
            {
                var metricUrl = $"https://ubet.com/api/sportsViewData/markets/false/{match.SourceId}";
                doc = await ScrapeHelper.GetDocument(metricUrl);

                jDoc = JsonConvert.DeserializeObject <JToken>(doc);
                var rawMetrics = jDoc
                                 .SelectTokens("$.All[?(@.GroupId == -1)].SubEvents[?(@.LongDisplayName =~ /(.* (Ttl|Total).*)/)]")
                                 .ToList();

                currentRange = Math.Min(currentRange + rangeProgress, 90);

                foreach (var rawMetric in rawMetrics)
                {
                    var betTypeShortName = rawMetric.SelectToken("$.BetTypeShortName").ToString();
                    var scoreType        =
                        betTypeShortName.Contains("Total Points Scored") ? ScoreType.Point :
                        betTypeShortName.Contains("Total Pts+Rebound+Assist") ? ScoreType.PointReboundAssist :
                        string.Empty;

                    betTypes.Add(betTypeShortName);

                    if (string.IsNullOrEmpty(scoreType))
                    {
                        continue;
                    }
                    var longDisplayName = rawMetric.SelectToken("$.LongDisplayName").ToString();
                    var playerName      = ScrapeHelper.RegexMappingExpression(longDisplayName, @"(.*)(?:Ttl|Total)");
                    var player          = ScrapeHelper.FindPlayerInMatch(playerName, match);
                    if (player == null)
                    {
                        Logger.Warning($"Cannot find any player {playerName} in match {match.Id}");
                        continue;
                    }

                    double?over = 0, overLine = 0, under = 0, underLine = 0;
                    var    offers = rawMetric.SelectTokens(@"$.Offers[?(@.OfferName =~ /(.* Over|Under|OV|UN .*)/)]");
                    foreach (var offer in offers)
                    {
                        var offerName = offer.SelectToken("$.OfferName").ToString();
                        if (offerName.Contains("Over") || offerName.Contains("OV"))
                        {
                            over     = ScrapeHelper.ConvertMetric(offer.SelectToken("$.WinReturn").ToString());
                            overLine = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(offerName, @".* (\d*.\d)"));
                        }
                        else if (offerName.Contains("Under") || offerName.Contains("UN"))
                        {
                            under     = ScrapeHelper.ConvertMetric(offer.SelectToken("$.WinReturn").ToString());
                            underLine = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(offerName, @".* (\d*.\d)"));
                        }
                    }

                    Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                    var metric = new PlayerOverUnder
                    {
                        MatchId               = match.Id,
                        Over                  = over,
                        OverLine              = overLine,
                        Under                 = under,
                        UnderLine             = underLine,
                        PlayerId              = player.Id,
                        ScoreType             = scoreType,
                        ScrapingInformationId = GetScrapingInformation().Id,
                        CreatedAt             = DateTime.Now
                    };

                    PlayerUnderOvers.Add(metric);

                    var newProgress = GetScrapingInformation().Progress;
                    newProgress = Math.Min(newProgress + currentRange / rawMetrics.Count, currentRange);
                    await UpdateScrapeStatus(newProgress, null);
                }
                await UpdateScrapeStatus(currentRange, null);
            }
            Logger.Information($"Unique scoreTypes: {JsonConvert.SerializeObject(betTypes)}"); // notify to update
            Logger.Information("Scrape metric data complete");
            await UpdateScrapeStatus(90, "Scrape metric data complete");
        }
        protected override async Task ScrapeData()
        {
            var chromeDriver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));

            try
            {
                const string url = "https://www.nextbet.com/en/sports/227-basketball/22892-usa/44178-nba";
                chromeDriver.Navigate().GoToUrl(url);
                await Task.Delay(10000);

                var doc = new HtmlDocument();
                doc.LoadHtml(chromeDriver.PageSource);
                var matchNodes = doc.DocumentNode.SelectNodes("//span[@class='period-description']");
                var rawMatches = matchNodes.Where(x => !x.InnerText.Contains("Tomorrow")).ToList();

                Logger.Information("Scrape metric data");
                await UpdateScrapeStatus(10, "Scraping metric data");

                var rangeProgress = rawMatches.Count != 0 ? 90 / rawMatches.Count : 0;
                var currentRange  = 10;
                for (var i = 0; i < rawMatches.Count; i++)
                {
                    chromeDriver.Navigate().GoToUrl(url);
                    await Task.Delay(10000);

                    var markets = chromeDriver.FindElementsByClassName("more_markets");
                    markets[i].Click();
                    await Task.Delay(10000);

                    doc.LoadHtml(chromeDriver.PageSource);

                    var marketContainer = doc.DocumentNode.SelectSingleNode("//div[@id='content']");
                    var marketGroups    = marketContainer.SelectNodes("//div[@class='markets-group-component']");
                    currentRange = Math.Min(currentRange + rangeProgress, 90);

                    foreach (var marketItem in marketGroups)
                    {
                        string scoreTypeItem;
                        try
                        {
                            scoreTypeItem = marketItem.SelectSingleNode("div/div/h2").InnerText;
                        }
                        catch (Exception)
                        {
                            continue;
                        }
                        var scoreType =
                            scoreTypeItem.Contains("Points + Assists") ? ScoreType.PointAssist :
                            scoreTypeItem.Contains("Points + Rebounds") ? ScoreType.PointRebound :
                            scoreTypeItem.Contains("Assists + Rebounds") ? ScoreType.ReboundAssist :
                            scoreTypeItem.Contains("Points + Assists + Rebounds") ? ScoreType.PointReboundAssist :
                            scoreTypeItem.Contains("Points") ? ScoreType.Point :
                            scoreTypeItem.Contains("Rebounds") ? ScoreType.Rebound :
                            scoreTypeItem.Contains("Assists") ? ScoreType.Assist :
                            scoreTypeItem.Contains("Three Made") ? ScoreType.ThreePoint :
                            string.Empty;

                        if (string.IsNullOrEmpty(scoreType) || scoreTypeItem.Contains("Odd/Even") ||
                            !scoreTypeItem.Contains("Match"))
                        {
                            continue;
                        }

                        doc.LoadHtml(marketItem.InnerHtml);
                        var playerMarkets = doc.DocumentNode.SelectNodes("//div[@class='market-component']");

                        foreach (var playerMarket in playerMarkets)
                        {
                            var playerName = playerMarket.SelectSingleNode("div[@class='player']").InnerText
                                             .Replace("\n", string.Empty)
                                             .Replace("\r", string.Empty)
                                             .Replace("\t", string.Empty)
                                             .Trim();

                            var match = ScrapeHelper.FindMatchByPlayerName(playerName, TodayMatches);
                            if (match == null)
                            {
                                continue;
                            }

                            var player = ScrapeHelper.FindPlayerInMatch(playerName, match);

                            var overLineItem = playerMarket.SelectSingleNode("div[@class='swish-markets-wrapper']/div/table/tbody/tr/td/span");
                            var overLineData = overLineItem.InnerText.Replace("\n", string.Empty).Replace("\r", string.Empty).Replace("\t", string.Empty).Trim();
                            var overLine     = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(overLineData, "Over (.*)"));

                            var priceOverData = playerMarket.SelectSingleNode("div[@class='swish-markets-wrapper']/div/table/tbody/tr/td/span[2]/span/span");
                            var over          = ScrapeHelper.ConvertMetric(priceOverData.InnerText.Replace("\n", string.Empty).Replace("\r", string.Empty).Replace("\t", string.Empty).Trim());

                            var underLineItem = playerMarket.SelectSingleNode("div[@class='swish-markets-wrapper']/div/table/tbody/tr/td[2]/span");
                            var underLineData = underLineItem.InnerText.Replace("\n", string.Empty).Replace("\r", string.Empty).Replace("\t", string.Empty).Trim();
                            var underLine     = ScrapeHelper.ConvertMetric(ScrapeHelper.RegexMappingExpression(underLineData, "Under (.*)"));

                            var priceUnderData = playerMarket.SelectSingleNode("div[@class='swish-markets-wrapper']/div/table/tbody/tr/td[2]/span[2]/span/span");
                            var under          = ScrapeHelper.ConvertMetric(priceUnderData.InnerText.Replace("\n", string.Empty).Replace("\r", string.Empty).Replace("\t", string.Empty).Trim());

                            Logger.Information($"{player.Name}: {scoreType} - {over} {overLine} | {under} {underLine}");

                            var metric = new PlayerOverUnder
                            {
                                MatchId               = match.Id,
                                Over                  = over,
                                OverLine              = overLine,
                                Under                 = under,
                                UnderLine             = underLine,
                                PlayerId              = player.Id,
                                ScoreType             = scoreType,
                                ScrapingInformationId = GetScrapingInformation().Id,
                                CreatedAt             = DateTime.Now
                            };

                            PlayerUnderOvers.Add(metric);

                            var newProgress = GetScrapingInformation().Progress;
                            newProgress = Math.Min(newProgress + currentRange / playerMarkets.Count, currentRange);
                            await UpdateScrapeStatus(newProgress, null);
                        }
                    }

                    await UpdateScrapeStatus(currentRange, null);
                }
                Logger.Information("Scrape metric data complete");
                await UpdateScrapeStatus(90, "Scrape metric data complete");
            }
            catch (Exception ex)
            {
                Logger.Error(ex.ToString());
                chromeDriver.Quit();
                throw;
            }
            chromeDriver.Quit();
        }