' ***********************************************************************
' Author : Elektro
' Last Modified On : 09-01-2014
' ***********************************************************************
' <copyright file="BetfairUtil.vb" company="Elektro Studios">
' Copyright (c) Elektro Studios. All rights reserved.
' </copyright>
' ***********************************************************************
#Region " Imports "
Imports HtmlAgilityPack
Imports System.Web
#End Region
''' <summary>
''' Contains web related methods for Betfair.
''' </summary>
Public Class BetfairUtil
#Region " XPath Expressions "
''' <summary>
''' XPath to locate the coming-up events grid.
''' </summary>
Private Shared ReadOnly XPathComingUpGrid As String = "//*/ul[1][@class='event-list']/li[@class='avb-row COMING_UP']/*"
''' <summary>
''' XPath to locate the home team name.
''' </summary>
Private Shared ReadOnly XPathHomeTeam As String = ".//span[@class='home-team-name']"
''' <summary>
''' XPath to locate the away team name.
''' </summary>
Private Shared ReadOnly XPathAwayTeam As String = ".//span[@class='away-team-name']"
''' <summary>
''' XPath to locate the day which the teams will play.
''' </summary>
Private Shared ReadOnly XPathPlayDay As String = ".//span[@class='date']"
''' <summary>
''' XPath to locate the hour at which the teams will play.
''' </summary>
Private Shared ReadOnly XPathPlayHour As String = XPathPlayDay
''' <summary>
''' XPath to locate the odds value 1.
''' </summary>
Private Shared ReadOnly XPathOddResult1 As String = ".//*/li[@class='selection sel-0']/*/span['ui-runner-price*']"
''' <summary>
''' XPath to locate the odds value 2.
''' </summary>
Private Shared ReadOnly XPathOddResult2 As String = ".//*/li[@class='selection sel-1']/*/span['ui-runner-price*']"
''' <summary>
''' XPath to locate the odds value 3.
''' </summary>
Private Shared ReadOnly XPathOddResult3 As String = ".//*/li[@class='selection sel-2']/*/span['ui-runner-price*']"
#End Region
#Region " Types "
''' <summary>
''' Specifies an event info.
''' </summary>
Public Class BetfairEventInfo
''' <summary>
''' Gets or sets the home team name.
''' </summary>
''' <value>The home team name.</value>
Public Property HomeTeam As String
''' <summary>
''' Gets or sets the away team name.
''' </summary>
''' <value>The away team name.</value>
Public Property AwayTeam As String
''' <summary>
''' Gets or sets the day which the teams will play.
''' </summary>
''' <value>The day which the teams will play.</value>
Public Property PlayDay As String
''' <summary>
''' Gets or sets the hour at which the teams will play.
''' </summary>
''' <value>The hour at which the teams will play.</value>
Public Property PlayHour As String
''' <summary>
''' Gets or sets the odds value for result '1'.
''' (which depending on the Betfair section could be the value for column-names: "1", "Yes" or "More than...")
''' </summary>
''' <value>The odds value for result '1'.</value>
Public Property Result1 As Double
''' <summary>
''' Gets or sets the odds value for result '2'.
''' (which depending on the Betfair section could be the value for column-names: "X", "No" or "Less than...")
''' </summary>
''' <value>The odds value for result '2'.</value>
Public Property Result2 As Double
''' <summary>
''' (which depending on the Betfair section could be the value for column-names: "2")
''' </summary>
''' <value>The odds value for result 'X'.</value>
Public Property ResultX As Double
End Class
#End Region
#Region " Public Methods "
''' <summary>
''' Gets the coming-up events from a Betfair page.
''' </summary>
''' <param name="HtmlSource">The Betfair webpage raw Html source-code to parse the events.</param>
''' <returns>List(Of EventInfo).</returns>
''' <exception cref="System.Exception">Node not found in the html source-code, maybe there is any coming-up event?</exception>
Public Shared Function GetComingUpEvents(ByVal HtmlSource As String) As List(Of BetfairEventInfo)
' The event collection to add events.
Dim EventInfoList As New List(Of BetfairEventInfo)
' The current event info.
Dim EventInfo As BetfairEventInfo
' Initialize the HtmlDoc object.
Dim Doc As New HtmlDocument
' Load the Html document.
Doc.LoadHtml(HtmlSource)
' A temporal node to determine whether the node exist.
Dim tempNode As HtmlNode
' The HtmlDocument nodes to analyze.
Dim Nodes As HtmlNodeCollection
' Select the Teams nodes.
Nodes = Doc.DocumentNode.SelectNodes(XPathComingUpGrid)
If Nodes Is Nothing Then ' Node not found in the html source-code.
Throw New Exception("Node not found in the html source-code, maybe there is any coming-up event?")
Return Nothing
End If
' Loop trough the nodes.
For Each Node As HtmlNode In Nodes
EventInfo = New BetfairEventInfo
' Retrieve and set the home team name.
EventInfo.HomeTeam = HttpUtility.HtmlDecode(Node.SelectSingleNode(XPathHomeTeam).InnerText.
Replace("(W)", String.Empty).
Replace("(HT)", String.Empty).
Replace("(QAT)", String.Empty).
Replace("(Uru)", String.Empty).
Replace("(Ecu)", String.Empty).
Replace("(Bol)", String.Empty).
Trim)
' Retrieve and set the away team name.
EventInfo.AwayTeam = HttpUtility.HtmlDecode(Node.SelectSingleNode(XPathAwayTeam).InnerText.
Replace("(W)", String.Empty).
Replace("(HT)", String.Empty).
Replace("(QAT)", String.Empty).
Replace("(Uru)", String.Empty).
Replace("(Ecu)", String.Empty).
Replace("(Bol)", String.Empty).
Trim)
' Retrieve and set the day which the teams will play.
tempNode = Node.SelectSingleNode(XPathPlayDay)
If tempNode IsNot Nothing Then
EventInfo.PlayDay = HttpUtility.HtmlDecode(Node.SelectSingleNode(XPathPlayDay).
InnerText.
Trim)
' This value can contains different words or one word;
' Such as: "Mañana 14:00" or "14:00" or "03 Sep 14".
' If the value is only the hour, the day is today.
If EventInfo.PlayDay Like "##:##" Then
EventInfo.PlayDay = "Hoy"
ElseIf EventInfo.PlayDay Like "Mañana*" Then
EventInfo.PlayDay = EventInfo.PlayDay.Split(" "c).First
End If
If Not EventInfo.PlayDay Like "## *" Then
' Retrieve and set the hour at which the teams will play.
EventInfo.PlayHour = HttpUtility.HtmlDecode(Node.SelectSingleNode(XPathPlayHour).
InnerText.
Trim.
Split(" "c).Last)
Else
EventInfo.PlayHour = "N/A" ' Unknown, the hour is not displayed.
End If
Else
EventInfo.PlayDay = "Error"
EventInfo.PlayHour = "Error"
End If
' Retrieve and set the odds for result '1'.
tempNode = Node.SelectSingleNode(XPathOddResult1) ' Test whether the node exists.
If tempNode IsNot Nothing Then
If String.IsNullOrEmpty(HttpUtility.HtmlDecode(Node.SelectSingleNode(XPathOddResult1).InnerText).Trim) _
OrElse String.IsNullOrWhiteSpace(HttpUtility.HtmlDecode(Node.SelectSingleNode(XPathOddResult1).InnerText).Trim) _
OrElse HttpUtility.HtmlDecode(Node.SelectSingleNode(XPathOddResult1).InnerText).Trim.Equals("NC", StringComparison.OrdinalIgnoreCase) Then
EventInfo.Result1 = 0
Else
EventInfo.Result1 = Node.SelectSingleNode(XPathOddResult1).InnerText.Trim().Replace(".", ",")
End If
Else
EventInfo.Result1 = 0
End If
' Retrieve and set the odds for result '2'.
tempNode = Node.SelectSingleNode(XPathOddResult2) ' Test whether the node exists.
If tempNode IsNot Nothing Then
If String.IsNullOrEmpty(HttpUtility.HtmlDecode(Node.SelectSingleNode(XPathOddResult2).InnerText).Trim) _
OrElse String.IsNullOrWhiteSpace(HttpUtility.HtmlDecode(Node.SelectSingleNode(XPathOddResult2).InnerText).Trim) _
OrElse HttpUtility.HtmlDecode(Node.SelectSingleNode(XPathOddResult2).InnerText).Trim.Equals("NC", StringComparison.OrdinalIgnoreCase) Then
EventInfo.Result2 = 0
Else
EventInfo.Result2 = Node.SelectSingleNode(XPathOddResult2).InnerText.Trim().Replace(".", ",")
End If
Else
EventInfo.Result2 = 0
End If
' Retrieve and set the odds for result 'X'.
tempNode = Node.SelectSingleNode(XPathOddResult3) ' Test whether the node exists.
If tempNode IsNot Nothing Then
If String.IsNullOrEmpty(HttpUtility.HtmlDecode(Node.SelectSingleNode(XPathOddResult3).InnerText).Trim) _
OrElse String.IsNullOrWhiteSpace(HttpUtility.HtmlDecode(Node.SelectSingleNode(XPathOddResult3).InnerText).Trim) _
OrElse HttpUtility.HtmlDecode(Node.SelectSingleNode(XPathOddResult3).InnerText).Trim.Equals("NC", StringComparison.OrdinalIgnoreCase) Then
EventInfo.ResultX = 0
Else
EventInfo.ResultX = Node.SelectSingleNode(XPathOddResult3).InnerText.Trim().Replace(".", ",")
End If
Else
EventInfo.ResultX = 0
End If
' Add the event-into into the event collection.
EventInfoList.Add(EventInfo)
Next Node
Return EventInfoList
End Function
#End Region
End Class