Compare commits

...

8 Commits

2 changed files with 223 additions and 330 deletions

View File

@@ -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("&pound;", "").Replace(",", ""), NumberStyles.AllowThousands);
var prizeFund = int.Parse(prizeFundNode.InnerText.Trim().Replace("&pound;", "").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("&pound;", "").Replace(",", ""), NumberStyles.AllowThousands);
var prizeFund5Bonus = int.Parse(prizeFund5BonusNode.InnerText.Trim().Replace("&pound;", "").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("&pound;", "").Replace(",", ""), NumberStyles.AllowThousands);
var prizeFund5 = int.Parse(prizeFund5Node.InnerText.Trim().Replace("&pound;", "").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("&pound;", "").Replace(",", ""), NumberStyles.AllowThousands);
var prizeFund4 = int.Parse(prizeFund4Node.InnerText.Trim().Replace("&pound;", "").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("&pound;", "").Replace(",", ""), NumberStyles.AllowThousands);
var prizeFund3 = int.Parse(prizeFund3Node.InnerText.Trim().Replace("&pound;", "").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("&pound;", "").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("&pound;", "").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("&pound;", "").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";
}
}
}

View File

@@ -2,11 +2,12 @@
{
class Program
{
static void Main()
static async Task Main()
{
using HttpClient client = new();
string url = "";
Lotto.GetLottoNumbers(url);
await Lotto.GetLottoNumbers(url, client);
}
}
}