|
|
|
|
@@ -7,346 +7,238 @@ namespace lottery_co_uk_scraper
|
|
|
|
|
{
|
|
|
|
|
internal class Lotto
|
|
|
|
|
{
|
|
|
|
|
public static void GetLottoNumbers(string url)
|
|
|
|
|
public static async Task GetLottoNumbers(string url, HttpClient client)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
using HttpClient client = new();
|
|
|
|
|
string html = client.GetStringAsync(url).Result;
|
|
|
|
|
string html = await client.GetStringAsync(url);
|
|
|
|
|
|
|
|
|
|
var doc = new HtmlDocument();
|
|
|
|
|
doc.LoadHtml(html);
|
|
|
|
|
|
|
|
|
|
var ballsDrawn = doc.DocumentNode.Descendants("span")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["id"] != null && x.Attributes["id"].Value == "ballsDrawn");
|
|
|
|
|
|
|
|
|
|
List<int>? lottoBalls = null;
|
|
|
|
|
List<int>? lottoBonusBalls = null;
|
|
|
|
|
|
|
|
|
|
if (ballsDrawn != null)
|
|
|
|
|
{
|
|
|
|
|
lottoBalls = ballsDrawn.Descendants("span")
|
|
|
|
|
.Where(x => x.Attributes["class"] != null && x.Attributes["class"].Value.Contains("lotto-ball"))
|
|
|
|
|
.Select(x => int.Parse(x.InnerText))
|
|
|
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
lottoBonusBalls = ballsDrawn.Descendants("span")
|
|
|
|
|
.Where(x => x.Attributes["class"] != null && x.Attributes["class"].Value.Contains("lotto-bonus-ball"))
|
|
|
|
|
.Select(x => int.Parse(x.InnerText))
|
|
|
|
|
.ToList();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lottoBalls != null)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Numbers inside lotto ball result: " + string.Join(", ", lottoBalls));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (lottoBonusBalls != null)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Numbers inside lotto bonus ball result: " + string.Join(", ", lottoBonusBalls));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var ballSetUsed = doc.DocumentNode.Descendants("td")
|
|
|
|
|
.Where(x => x.InnerHtml.Contains("<strong>Ball Set Used:</strong>"))
|
|
|
|
|
.Select(x => x.InnerText.Split(':')[1].Trim())
|
|
|
|
|
.FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
var machineName = doc.DocumentNode.Descendants("td")
|
|
|
|
|
.Where(x => x.InnerHtml.Contains("<strong>Ball Machine Used:</strong>"))
|
|
|
|
|
.Select(x => x.InnerText.Split(':')[1].Trim())
|
|
|
|
|
.FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
var table = doc.DocumentNode.Descendants("table")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["class"] != null && x.Attributes["class"].Value.Contains("lotto mobFormat"));
|
|
|
|
|
|
|
|
|
|
if (table != null)
|
|
|
|
|
{
|
|
|
|
|
var match6Row = table.Descendants("tr")
|
|
|
|
|
.FirstOrDefault(x => x.Descendants("td")
|
|
|
|
|
.Any(y => y.InnerHtml.Contains("<strong>Match 6</strong>")));
|
|
|
|
|
|
|
|
|
|
if (match6Row != null)
|
|
|
|
|
{
|
|
|
|
|
var match6WinnersNode = match6Row.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Winners");
|
|
|
|
|
|
|
|
|
|
var prizePerWinnerNode = match6Row.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Prize Per Winner");
|
|
|
|
|
|
|
|
|
|
var prizeFundNode = match6Row.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Prize Fund Amount");
|
|
|
|
|
|
|
|
|
|
if (match6WinnersNode != null && prizePerWinnerNode != null && prizeFundNode != null)
|
|
|
|
|
{
|
|
|
|
|
var match6Winners = int.Parse(match6WinnersNode.InnerText.Trim().Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
var prizePerWinner = int.Parse(prizePerWinnerNode.InnerText.Trim().Replace("£", "").Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
var prizeFund = int.Parse(prizeFundNode.InnerText.Trim().Replace("£", "").Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Match 6 winners: " + match6Winners);
|
|
|
|
|
Console.WriteLine("Prize per winner: " + prizePerWinner);
|
|
|
|
|
Console.WriteLine("Prize fund: " + prizeFund);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var match5BonusRow = table.Descendants("tr")
|
|
|
|
|
.FirstOrDefault(x => x.Descendants("td")
|
|
|
|
|
.Any(y => y.InnerHtml.Contains("<strong>Match 5 plus Bonus</strong>")));
|
|
|
|
|
|
|
|
|
|
if (match5BonusRow != null)
|
|
|
|
|
{
|
|
|
|
|
var match5BonusWinnersNode = match5BonusRow.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Winners");
|
|
|
|
|
|
|
|
|
|
var prizePerWinner5BonusNode = match5BonusRow.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Prize Per Winner");
|
|
|
|
|
|
|
|
|
|
var prizeFund5BonusNode = match5BonusRow.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Prize Fund Amount");
|
|
|
|
|
|
|
|
|
|
if (match5BonusWinnersNode != null && prizePerWinner5BonusNode != null && prizeFund5BonusNode != null)
|
|
|
|
|
{
|
|
|
|
|
var match5BonusWinners = int.Parse(match5BonusWinnersNode.InnerText.Trim().Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
var prizePerWinner5Bonus = int.Parse(prizePerWinner5BonusNode.InnerText.Trim().Replace("£", "").Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
var prizeFund5Bonus = int.Parse(prizeFund5BonusNode.InnerText.Trim().Replace("£", "").Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Match 5 plus Bonus winners: " + match5BonusWinners);
|
|
|
|
|
Console.WriteLine("Prize per winner (Match 5 plus Bonus): " + prizePerWinner5Bonus);
|
|
|
|
|
Console.WriteLine("Prize fund (Match 5 plus Bonus): " + prizeFund5Bonus);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var match5Row = table.Descendants("tr")
|
|
|
|
|
.FirstOrDefault(x => x.Descendants("td")
|
|
|
|
|
.Any(y => y.InnerHtml.Contains("<strong>Match 5</strong>")));
|
|
|
|
|
|
|
|
|
|
if (match5Row != null)
|
|
|
|
|
{
|
|
|
|
|
var match5WinnersNode = match5Row.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Winners");
|
|
|
|
|
|
|
|
|
|
var prizePerWinner5Node = match5Row.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Prize Per Winner");
|
|
|
|
|
|
|
|
|
|
var prizeFund5Node = match5Row.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Prize Fund Amount");
|
|
|
|
|
|
|
|
|
|
if (match5WinnersNode != null && prizePerWinner5Node != null && prizeFund5Node != null)
|
|
|
|
|
{
|
|
|
|
|
var match5Winners = int.Parse(match5WinnersNode.InnerText.Trim().Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
var prizePerWinner5 = int.Parse(prizePerWinner5Node.InnerText.Trim().Replace("£", "").Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
var prizeFund5 = int.Parse(prizeFund5Node.InnerText.Trim().Replace("£", "").Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Match 5 winners: " + match5Winners);
|
|
|
|
|
Console.WriteLine("Prize per winner (Match 5): " + prizePerWinner5);
|
|
|
|
|
Console.WriteLine("Prize fund (Match 5): " + prizeFund5);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var match4Row = table.Descendants("tr")
|
|
|
|
|
.FirstOrDefault(x => x.Descendants("td")
|
|
|
|
|
.Any(y => y.InnerHtml.Contains("<strong>Match 4</strong>")));
|
|
|
|
|
|
|
|
|
|
if (match4Row != null)
|
|
|
|
|
{
|
|
|
|
|
var match4WinnersNode = match4Row.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Winners");
|
|
|
|
|
|
|
|
|
|
var prizePerWinner4Node = match4Row.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Prize Per Winner");
|
|
|
|
|
|
|
|
|
|
var prizeFund4Node = match4Row.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Prize Fund Amount");
|
|
|
|
|
|
|
|
|
|
if (match4WinnersNode != null && prizePerWinner4Node != null && prizeFund4Node != null)
|
|
|
|
|
{
|
|
|
|
|
var match4Winners = int.Parse(match4WinnersNode.InnerText.Trim().Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
var prizePerWinner4 = int.Parse(prizePerWinner4Node.InnerText.Trim().Replace("£", "").Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
var prizeFund4 = int.Parse(prizeFund4Node.InnerText.Trim().Replace("£", "").Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Match 4 winners: " + match4Winners);
|
|
|
|
|
Console.WriteLine("Prize per winner (Match 4): " + prizePerWinner4);
|
|
|
|
|
Console.WriteLine("Prize fund (Match 4): " + prizeFund4);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var match3Row = table.Descendants("tr")
|
|
|
|
|
.FirstOrDefault(x => x.Descendants("td")
|
|
|
|
|
.Any(y => y.InnerHtml.Contains("<strong>Match 3</strong>")));
|
|
|
|
|
|
|
|
|
|
if (match3Row != null)
|
|
|
|
|
{
|
|
|
|
|
var match3WinnersNode = match3Row.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Winners");
|
|
|
|
|
|
|
|
|
|
var prizePerWinner3Node = match3Row.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Prize Per Winner");
|
|
|
|
|
|
|
|
|
|
var prizeFund3Node = match3Row.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Prize Fund Amount");
|
|
|
|
|
|
|
|
|
|
if (match3WinnersNode != null && prizePerWinner3Node != null && prizeFund3Node != null)
|
|
|
|
|
{
|
|
|
|
|
var match3Winners = int.Parse(match3WinnersNode.InnerText.Trim().Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
var prizePerWinner3 = int.Parse(prizePerWinner3Node.InnerText.Trim().Replace("£", "").Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
var prizeFund3 = int.Parse(prizeFund3Node.InnerText.Trim().Replace("£", "").Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Match 3 winners: " + match3Winners);
|
|
|
|
|
Console.WriteLine("Prize per winner (Match 3): " + prizePerWinner3);
|
|
|
|
|
Console.WriteLine("Prize fund (Match 3): " + prizeFund3);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var totalsRow = table.Descendants("tr")
|
|
|
|
|
.FirstOrDefault(x => x.Descendants("td")
|
|
|
|
|
.Any(y => y.InnerHtml.Contains("<strong>Totals</strong>")));
|
|
|
|
|
|
|
|
|
|
if (totalsRow != null)
|
|
|
|
|
{
|
|
|
|
|
var totalWinnersNode = totalsRow.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Winners");
|
|
|
|
|
|
|
|
|
|
var totalPrizeFundNode = totalsRow.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Prize Fund Amount");
|
|
|
|
|
|
|
|
|
|
if (totalWinnersNode != null && totalPrizeFundNode != null)
|
|
|
|
|
{
|
|
|
|
|
var totalWinners = int.Parse(totalWinnersNode.InnerText.Trim().Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
var totalPrizeFund = int.Parse(totalPrizeFundNode.InnerText.Trim().Replace("£", "").Replace(",", ""), NumberStyles.AllowThousands);
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Total winners: " + totalWinners);
|
|
|
|
|
Console.WriteLine("Total prize fund: " + totalPrizeFund);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var metaKeywords = doc.DocumentNode.Descendants("meta")
|
|
|
|
|
.FirstOrDefault(x => x.GetAttributeValue("name", "") == "keywords");
|
|
|
|
|
|
|
|
|
|
if (metaKeywords != null)
|
|
|
|
|
{
|
|
|
|
|
var keywordsText = metaKeywords.GetAttributeValue("content", "");
|
|
|
|
|
var drawNumberMatch = Regex.Match(keywordsText, @"lotto draw (\d+)");
|
|
|
|
|
|
|
|
|
|
if (drawNumberMatch.Success)
|
|
|
|
|
{
|
|
|
|
|
var drawNumber = int.Parse(drawNumberMatch.Groups[1].Value);
|
|
|
|
|
Console.WriteLine("Draw Number: " + drawNumber);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Draw Number not found.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Meta keywords not found.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var title = doc.DocumentNode.Descendants("title")
|
|
|
|
|
.FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
if (title != null)
|
|
|
|
|
{
|
|
|
|
|
var titleText = title.InnerText;
|
|
|
|
|
var date = TextRemoval.ParseDateString(titleText);
|
|
|
|
|
|
|
|
|
|
string formattedDate = date.ToString("yyyy-MM-dd");
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Draw Date: " + formattedDate);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Title not found.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var rolloverElement = doc.DocumentNode.Descendants("span")
|
|
|
|
|
.FirstOrDefault(x => x.InnerText.Trim() == "Rollover");
|
|
|
|
|
|
|
|
|
|
bool rollover = rolloverElement != null;
|
|
|
|
|
|
|
|
|
|
var rolldownElement = doc.DocumentNode.Descendants("span")
|
|
|
|
|
.FirstOrDefault(x => x.InnerText.Trim() == "Rolldown");
|
|
|
|
|
|
|
|
|
|
bool rolldown = rolldownElement != null;
|
|
|
|
|
|
|
|
|
|
if (rollover == true)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Rollover: " + rollover);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rolldown == true)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Rolldown: " + rolldown);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Ball set used: " + ballSetUsed);
|
|
|
|
|
Console.WriteLine("Machine Name: " + machineName);
|
|
|
|
|
ProcessBalls(doc);
|
|
|
|
|
ProcessWinnersTable(doc);
|
|
|
|
|
ProcessMetaInformation(doc);
|
|
|
|
|
}
|
|
|
|
|
catch (HttpRequestException ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"HTTP request error: {ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"An error occurred: {ex.Message}");
|
|
|
|
|
}
|
|
|
|
|
finally
|
|
|
|
|
{
|
|
|
|
|
client.Dispose();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void ProcessBalls(HtmlDocument doc)
|
|
|
|
|
{
|
|
|
|
|
var ballsDrawn = doc.DocumentNode.Descendants("span")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["id"] != null && x.Attributes["id"].Value == "ballsDrawn");
|
|
|
|
|
|
|
|
|
|
List<int>? lottoBalls = (ballsDrawn != null)
|
|
|
|
|
? ExtractBalls(ballsDrawn, "lotto-ball")
|
|
|
|
|
: null;
|
|
|
|
|
|
|
|
|
|
List<int>? lottoBonusBalls = (ballsDrawn != null)
|
|
|
|
|
? ExtractBalls(ballsDrawn, "lotto-bonus-ball")
|
|
|
|
|
: null;
|
|
|
|
|
|
|
|
|
|
PrintResults("Numbers inside lotto ball result", lottoBalls);
|
|
|
|
|
PrintResults("Numbers inside lotto bonus ball result", lottoBonusBalls);
|
|
|
|
|
|
|
|
|
|
var ballSetUsed = doc.DocumentNode.Descendants("td")
|
|
|
|
|
.Where(x => x.InnerHtml.Contains("<strong>Ball Set Used:</strong>"))
|
|
|
|
|
.Select(x => x.InnerText.Split(':')[1].Trim())
|
|
|
|
|
.FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
var machineName = doc.DocumentNode.Descendants("td")
|
|
|
|
|
.Where(x => x.InnerHtml.Contains("<strong>Ball Machine Used:</strong>"))
|
|
|
|
|
.Select(x => x.InnerText.Split(':')[1].Trim())
|
|
|
|
|
.FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Ball set used: " + ballSetUsed);
|
|
|
|
|
Console.WriteLine("Machine Name: " + machineName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static List<int> ExtractBalls(HtmlNode ballsNode, string className)
|
|
|
|
|
{
|
|
|
|
|
return ballsNode.Descendants("span")
|
|
|
|
|
.Where(x => x.Attributes["class"] != null && x.Attributes["class"].Value.Contains(className))
|
|
|
|
|
.Select(x =>
|
|
|
|
|
{
|
|
|
|
|
if (int.TryParse(x.InnerText, out int ball))
|
|
|
|
|
{
|
|
|
|
|
return ball;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Console.WriteLine($"Failed to parse {className} value: {x.InnerText}");
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
})
|
|
|
|
|
.ToList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void ProcessWinnersTable(HtmlDocument doc)
|
|
|
|
|
{
|
|
|
|
|
var table = doc.DocumentNode.Descendants("table")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["class"] != null && x.Attributes["class"].Value.Contains("lotto mobFormat"));
|
|
|
|
|
|
|
|
|
|
if (table != null)
|
|
|
|
|
{
|
|
|
|
|
ProcessTableSection(table, LotteryConstants.Match6);
|
|
|
|
|
ProcessTableSection(table, LotteryConstants.Match5Bonus);
|
|
|
|
|
ProcessTableSection(table, LotteryConstants.Match5);
|
|
|
|
|
ProcessTableSection(table, LotteryConstants.Match4);
|
|
|
|
|
ProcessTableSection(table, LotteryConstants.Match3);
|
|
|
|
|
ProcessTableSection(table, LotteryConstants.Totals);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void ProcessTableSection(HtmlNode table, string sectionTitle)
|
|
|
|
|
{
|
|
|
|
|
var sectionRow = table.Descendants("tr")
|
|
|
|
|
.FirstOrDefault(x => x.Descendants("td").Any(y => y.InnerHtml.Contains($"<strong>{sectionTitle}</strong>")));
|
|
|
|
|
|
|
|
|
|
if (sectionRow != null)
|
|
|
|
|
{
|
|
|
|
|
var winnersNode = sectionRow.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Winners");
|
|
|
|
|
|
|
|
|
|
var prizePerWinnerNode = sectionRow.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Prize Per Winner");
|
|
|
|
|
|
|
|
|
|
var prizeFundNode = sectionRow.Descendants("td")
|
|
|
|
|
.FirstOrDefault(x => x.Attributes["data-title"] != null && x.Attributes["data-title"].Value == "Prize Fund Amount");
|
|
|
|
|
|
|
|
|
|
if (winnersNode != null && prizePerWinnerNode != null && prizeFundNode != null)
|
|
|
|
|
{
|
|
|
|
|
if (int.TryParse(winnersNode.InnerText.Trim().Replace(",", ""), NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out int winners))
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"{sectionTitle} winners: {winners}");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"Failed to parse {sectionTitle} winners.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (int.TryParse(prizePerWinnerNode.InnerText.Trim().Replace("£", "").Replace(",", ""), NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out int prizePerWinner))
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"Prize per winner ({sectionTitle}): {prizePerWinner}");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"Failed to parse prize per winner ({sectionTitle}).");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (int.TryParse(prizeFundNode.InnerText.Trim().Replace("£", "").Replace(",", ""), NumberStyles.AllowThousands, CultureInfo.InvariantCulture, out int prizeFund))
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"Prize fund ({sectionTitle}): {prizeFund}");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"Failed to parse prize fund ({sectionTitle}).");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Handle the case when some nodes are not found
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Handle the case when the section row is not found
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void ProcessMetaInformation(HtmlDocument doc)
|
|
|
|
|
{
|
|
|
|
|
var metaKeywords = doc.DocumentNode.Descendants("meta")
|
|
|
|
|
.FirstOrDefault(x => x.GetAttributeValue("name", "") == "keywords");
|
|
|
|
|
|
|
|
|
|
if (metaKeywords != null)
|
|
|
|
|
{
|
|
|
|
|
var keywordsText = metaKeywords.GetAttributeValue("content", "");
|
|
|
|
|
var drawNumberMatch = Regex.Match(keywordsText, @"lotto draw (\d+)");
|
|
|
|
|
|
|
|
|
|
if (drawNumberMatch.Success)
|
|
|
|
|
{
|
|
|
|
|
if (int.TryParse(drawNumberMatch.Groups[1].Value, out int drawNumber))
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Draw Number: " + drawNumber);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Failed to parse draw number.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Draw Number not found.");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Meta keywords not found.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var title = doc.DocumentNode.Descendants("title")
|
|
|
|
|
.FirstOrDefault();
|
|
|
|
|
|
|
|
|
|
if (title != null)
|
|
|
|
|
{
|
|
|
|
|
var titleText = title.InnerText;
|
|
|
|
|
var date = TextRemoval.ParseDateString(titleText);
|
|
|
|
|
|
|
|
|
|
string formattedDate = date.ToString("yyyy-MM-dd");
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Draw Date: " + formattedDate);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Title not found.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var rolloverElement = doc.DocumentNode.Descendants("span")
|
|
|
|
|
.FirstOrDefault(x => x.InnerText.Trim() == "Rollover");
|
|
|
|
|
|
|
|
|
|
bool rollover = rolloverElement != null;
|
|
|
|
|
|
|
|
|
|
var rolldownElement = doc.DocumentNode.Descendants("span")
|
|
|
|
|
.FirstOrDefault(x => x.InnerText.Trim() == "Rolldown");
|
|
|
|
|
|
|
|
|
|
bool rolldown = rolldownElement != null;
|
|
|
|
|
|
|
|
|
|
if (rollover)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Rollover: " + rollover);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rolldown)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Rolldown: " + rolldown);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void PrintResults(string label, List<int>? values)
|
|
|
|
|
{
|
|
|
|
|
if (values != null)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine($"{label}: " + string.Join(", ", values));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static class LotteryConstants
|
|
|
|
|
{
|
|
|
|
|
public const string Match6 = "Match 6";
|
|
|
|
|
public const string Match5Bonus = "Match 5 plus Bonus";
|
|
|
|
|
public const string Match5 = "Match 5";
|
|
|
|
|
public const string Match4 = "Match 4";
|
|
|
|
|
public const string Match3 = "Match 3";
|
|
|
|
|
public const string Totals = "Totals";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|