├── tempCodeRunnerFile.py ├── __pycache__ ├── Calculations.cpython-37.pyc ├── OddsScrapper.cpython-37.pyc ├── Calculations.cpython-310.pyc └── OddsScrapper.cpython-310.pyc ├── Debugging ├── __pycache__ │ ├── CalculationsDebug.cpython-310.pyc │ └── OddsScrapperDebug.cpython-310.pyc ├── MainDebug.py ├── CalculationsDebug.py └── OddsScrapperDebug.py ├── README.md ├── Main.py ├── Calculations.py └── OddsScrapper.py /tempCodeRunnerFile.py: -------------------------------------------------------------------------------- 1 | 2 | # msgArray = s.arbitrage(msgArray) -------------------------------------------------------------------------------- /__pycache__/Calculations.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XixWISExiX/Sports-Betting-Arbitrage-Bot/HEAD/__pycache__/Calculations.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/OddsScrapper.cpython-37.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XixWISExiX/Sports-Betting-Arbitrage-Bot/HEAD/__pycache__/OddsScrapper.cpython-37.pyc -------------------------------------------------------------------------------- /__pycache__/Calculations.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XixWISExiX/Sports-Betting-Arbitrage-Bot/HEAD/__pycache__/Calculations.cpython-310.pyc -------------------------------------------------------------------------------- /__pycache__/OddsScrapper.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XixWISExiX/Sports-Betting-Arbitrage-Bot/HEAD/__pycache__/OddsScrapper.cpython-310.pyc -------------------------------------------------------------------------------- /Debugging/__pycache__/CalculationsDebug.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XixWISExiX/Sports-Betting-Arbitrage-Bot/HEAD/Debugging/__pycache__/CalculationsDebug.cpython-310.pyc -------------------------------------------------------------------------------- /Debugging/__pycache__/OddsScrapperDebug.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/XixWISExiX/Sports-Betting-Arbitrage-Bot/HEAD/Debugging/__pycache__/OddsScrapperDebug.cpython-310.pyc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sports-Betting-Arbitrage-Bot 2 | A bot which automates the process of finding betting odds by web scrapping and then calculates to see if there is an Arbitrage Opportunity. 3 | (Arbitrage means that you can bet on the two opposing sides and never lose money, but you can still make money) 4 | 5 | For web scrapping I used Selenium to make the sure that the program takes the new updated values on various sports betting web sites. 6 | Then I converted those odds to decimal odds and found if there is Arbitrage in those matches. Mathmatically this is a very rare chance, 7 | and is only a thing when the implied probability is less that 100% or 1. 8 | 9 | *Will be updated soon* 10 | -------------------------------------------------------------------------------- /Debugging/MainDebug.py: -------------------------------------------------------------------------------- 1 | from OddsScrapperDebug import Scraper 2 | 3 | # Creats a scraper object to then scrap data through various means and then find arbitrage afterwards 4 | s = Scraper() 5 | # TODO if odds are heavaly scewed, then there might be something wrong 6 | 7 | msgArray = [] 8 | 9 | s.oddsSharkMMA() 10 | msgArray = s.arbitrage(msgArray) 11 | s.clearData() 12 | 13 | s.oddsSharkNHL() 14 | msgArray = s.arbitrage(msgArray) 15 | s.clearData() 16 | 17 | s.oddsSharkNBA() 18 | msgArray = s.arbitrage(msgArray) 19 | s.clearData() 20 | 21 | s.oddsSharkMLB() 22 | msgArray = s.arbitrage(msgArray) 23 | s.clearData() 24 | 25 | #TODO might need to check if the same 2 teams are having a match on a different day (could be a future bug) -------------------------------------------------------------------------------- /Main.py: -------------------------------------------------------------------------------- 1 | from OddsScrapper import Scraper 2 | import time 3 | import smtplib 4 | from threading import Timer 5 | 6 | # Creats a scraper object to then scrap data through various means and then find arbitrage afterwards 7 | s = Scraper() 8 | # TODO if odds are heavaly scewed, then there might be something wrong 9 | 10 | # TODO if the site is down then the program might shut down 11 | 12 | # A dummy method to plug into the timer 13 | def dummyMethod(val): 14 | val = "done" 15 | 16 | # Method which restest the timer 17 | def reset(timer, interval, function): 18 | timer.cancel() 19 | timer = Timer(interval, function) 20 | timer.start() 21 | 22 | # There are 86400 seconds in a day (message array refreshes every 24 hours) 23 | tmr = Timer(86400, dummyMethod, []) 24 | tmr.start() 25 | msgArray = ["mogus"] 26 | 27 | try: 28 | while(True): 29 | if(not tmr.is_alive()): 30 | reset(tmr, dummyMethod, ["ok"]) 31 | msgArray = [] 32 | 33 | s.testData1() 34 | msgArray = s.arbitrage(msgArray) 35 | s.clearData() 36 | 37 | # s.oddsSharkMMA() 38 | # msgArray = s.arbitrage(msgArray) 39 | # s.clearData() 40 | 41 | # s.oddsSharkNHL() 42 | # msgArray = s.arbitrage(msgArray) 43 | # s.clearData() 44 | 45 | # s.oddsSharkNBA() 46 | # msgArray = s.arbitrage(msgArray) 47 | # s.clearData() 48 | 49 | # s.draftKingsMMA() 50 | # s.CaesarsMMA() 51 | # # s.FanduelMMA() #TODO this one doesn't work. add ones that do or just make it work 52 | # msgArray = s.arbitrage(msgArray) 53 | # s.clearData() 54 | 55 | #TODO make change 56 | # s.oddsSharkMLB() 57 | # msgArray = s.arbitrage(msgArray) 58 | # s.clearData() 59 | 60 | break 61 | except: 62 | server = smtplib.SMTP_SSL("smtp.gmail.com", 465) 63 | # OLD METHOD -> server.login("WiseBetz100@gmail.com", "Fr33M0n3y.") 64 | server.login("WiseBetz100@gmail.com", "wrpierwlyhfdeujv") 65 | server.sendmail("WiseBetz100@gmail.com", 66 | "ReceiverOfGoodNews@gmail.com", 67 | "Program has ended") 68 | server.quit() 69 | 70 | #TODO might need to check if the same 2 teams are having a match on a different day (could be a future bug) -------------------------------------------------------------------------------- /Debugging/CalculationsDebug.py: -------------------------------------------------------------------------------- 1 | import smtplib 2 | # Imports the main grid variable from odds Scrapper (calculates arbitrage with the format given from the scrapper class) 3 | # Only calculates arbitrage for 2 possible out comes, meaning no parlays and no draw odds. 4 | class Calculations: 5 | def __init__(self, grid, sportName) -> None: 6 | # The grid to preform calculations on 7 | self.grid = grid 8 | 9 | # Name of the given sport 10 | self.sportName = sportName 11 | 12 | # The email message which is going to be emailed when there is arbitrage 13 | self.emailMessage = "" 14 | 15 | self.emailMsgArray = [] 16 | 17 | # The Implied Probability 18 | self.impProb = 101 19 | 20 | # Name of arbitrage site 1 and 2 21 | self.site1 = None 22 | self.site2 = None 23 | 24 | # Name of arbitrage players 1 and 2 25 | self.team1 = None 26 | self.team2 = None 27 | 28 | # odds of bet 1 and bet 2 29 | self.betOdds1 = None 30 | self.betOdds2 = None 31 | 32 | # index position of player 1 33 | self.index = None 34 | # index position of site 1 35 | self.index1 = None 36 | # index position of site 2 37 | self.index2 = None 38 | 39 | # Gets the Email Message Array 40 | def getEmailMsgArray(self): 41 | return self.emailMsgArray 42 | 43 | # Sets the Email Message Array 44 | def setEmailMsgArray(self, array): 45 | self.emailMsgArray = array 46 | 47 | # Prints the grid 48 | def print(self): 49 | print(self.grid) 50 | 51 | # Prints the Arbitrage site, name, and odds of both sides of the given match 52 | def teamComparison(self): 53 | print("======") 54 | print("Implied Probability: ",self.impProb) 55 | print("-----") 56 | print("Sport :",self.sportName) 57 | print("Site 1: ",self.site1, "| Team Name: ",self.team1, "| Odds: ",self.betOdds1) 58 | print("Site 2: ",self.site2, "| Team Name: ",self.team2, "| Odds: ",self.betOdds2) 59 | print("-----") 60 | # self.emailMessage+="======\n" 61 | # self.emailMessage+="Implied Probability: {}\n".format(self.impProb) 62 | # self.emailMessage+="-----\n" 63 | # self.emailMessage+="Sport : {}\n".format(self.sportName) 64 | # self.emailMessage+="Site 1: {} | Team Name: {} | Odds: {}\n".format(self.site1, self.team1, self.betOdds1) 65 | # self.emailMessage+="Site 2: {} | Team Name: {} | Odds: {}\n".format(self.site2, self.team2, self.betOdds2) 66 | # self.emailMessage+="-----\n" 67 | 68 | def emailUser(self): 69 | server = smtplib.SMTP_SSL("smtp.gmail.com", 465) 70 | # server.login("WiseBetz100@gmail.com", "Fr33M0n3y.") 71 | # server.sendmail("WiseBetz100@gmail.com", 72 | # "ReceiverOfGoodNews@gmail.com", 73 | # self.emailMessage) 74 | server.quit() 75 | 76 | # Converts american odds to decimal odds 77 | def toDecimal(self, american_odds): 78 | if(american_odds<0): 79 | return (100/abs(american_odds))+1 80 | else: 81 | return (american_odds/100)+1 82 | 83 | # Converts both odds to implied probability (arbitrage is less than 100% or 1) 84 | def impliedProbability(self, odds1, odds2): 85 | return (1/self.toDecimal(odds1))+(1/self.toDecimal(odds2)) 86 | 87 | 88 | # Determins if 2 odds have Arbitrage and if so, returns true. This method also prints out arbitrage information to the user 89 | def isArbitrage(self, odds1, odds2): 90 | impProb = self.impliedProbability(odds1, odds2) 91 | wasEmailed = False 92 | if(impProb < 1): 93 | self.betOdds1 = odds1 94 | self.betOdds2 = odds2 95 | self.site1 = self.grid[0][self.index1] 96 | self.site2 = self.grid[0][self.index2] 97 | self.team1 = self.grid[self.index][0] 98 | self.team2 = self.grid[self.index+1][0] 99 | self.impProb = impProb 100 | # print("======") 101 | # print("Implied Probability is", impProb) 102 | self.teamComparison() 103 | #TODO might want to grab multiple arbitrage oportunities if you can (program doesn't do that yet) 104 | # assumed pay out is $100 105 | self.moneyRatio(odds1, odds2, 100) 106 | 107 | # for array in self.emailMsgArray: 108 | # if(array == self.emailMessage): 109 | # wasEmailed = True 110 | # if(not wasEmailed): 111 | # self.emailUser() 112 | # self.emailMsgArray.append(self.emailMessage) 113 | 114 | return True 115 | return False 116 | 117 | # Finds if there is arbitrage in the grid 118 | def anyArbitrage(self, grids): 119 | r=1 120 | hasArb = False 121 | while(rlarge1): 154 | large1 = matchSet[0][i] 155 | self.index1 = i 156 | # Finds the largest value for the second set 157 | large2 = -100000 158 | for i in range(len(matchSet[1])): 159 | if(matchSet[1][i] != None): 160 | if(matchSet[1][i]>large2): 161 | large2 = matchSet[1][i] 162 | self.index2 = i 163 | # Calls the is arbitrage function to see if the two largest numbers are arbitrage 164 | return self.isArbitrage(large1,large2) 165 | 166 | # Finds out how much money should be put down (with the assuming price of total money put down) along with the ratio (if arbitrage) 167 | def moneyRatio(self, odds1, odds2, payout): 168 | #TODO https://thearbacademy.com/arbitrage-calculation/ this website might help 169 | 170 | # Gets decimal odds to perform calcultions 171 | odd1 = self.toDecimal(odds1) 172 | odd2 = self.toDecimal(odds2) 173 | 174 | # Determins how much money to stake on both sides of the bet 175 | stake1 = (payout)/odd1 176 | stake2 = (payout)/odd2 177 | 178 | # Determins the ratio to stake on both sides of the bet 179 | ratio1 = stake1/stake2 180 | ratio2 = stake2/stake1 181 | 182 | #TODO double cheek of ratio works as intended 183 | # Prints the information to the user 184 | 185 | print("Bet $%f" %stake1, "on", self.team1, "to win $%f" %(payout - stake1), "profit. Bet 1 needs", ratio1, "times more than Bet 2.") 186 | print("Bet $%f" %stake2, "on", self.team2, "to win $%f" %(payout - stake2), "profit. Bet 2 needs", ratio2, "times more than Bet 1.") 187 | print("Net profit is $", payout-stake1-stake2) 188 | print("======") 189 | 190 | # self.emailMessage+="Bet ${} on {} to win ${} profit. Bet 1 needs {} times more than Bet 2.\n".format(stake1, self.team1, (payout - stake1), ratio1) 191 | # self.emailMessage+="Bet ${} on {} to win ${} profit. Bet 2 needs {} times more than Bet 2.\n".format(stake2, self.team2, (payout - stake2), ratio2) 192 | # self.emailMessage+="Net profit is ${}\n".format(payout-stake1-stake2) 193 | # self.emailMessage+="======\n" -------------------------------------------------------------------------------- /Calculations.py: -------------------------------------------------------------------------------- 1 | import smtplib 2 | # Imports the main grid variable from odds Scrapper (calculates arbitrage with the format given from the scrapper class) 3 | # Only calculates arbitrage for 2 possible out comes, meaning no parlays and no draw odds. 4 | 5 | # https://www.pinnacle.com/en/betting-resources/betting-tools/arbitrage-calculator 6 | 7 | class Calculations: 8 | def __init__(self, grid, sportName) -> None: 9 | # The grid to preform calculations on 10 | self.grid = grid 11 | 12 | # Name of the given sport 13 | self.sportName = sportName 14 | 15 | # The email message which is going to be emailed when there is arbitrage 16 | self.emailMessage = "" 17 | 18 | self.emailMsgArray = [] 19 | 20 | # The Implied Probability 21 | self.impProb = 101 22 | 23 | # Name of arbitrage site 1 and 2 24 | self.site1 = None 25 | self.site2 = None 26 | 27 | # Name of arbitrage players 1 and 2 28 | self.team1 = None 29 | self.team2 = None 30 | 31 | # odds of bet 1 and bet 2 32 | self.betOdds1 = None 33 | self.betOdds2 = None 34 | 35 | # index position of player 1 36 | self.index = None 37 | # index position of site 1 38 | self.index1 = None 39 | # index position of site 2 40 | self.index2 = None 41 | 42 | # Gets the Email Message Array 43 | def getEmailMsgArray(self): 44 | return self.emailMsgArray 45 | 46 | # Sets the Email Message Array 47 | def setEmailMsgArray(self, array): 48 | self.emailMsgArray = array 49 | 50 | # Prints the grid 51 | def print(self): 52 | print(self.grid) 53 | 54 | # Prints the Arbitrage site, name, and odds of both sides of the given match 55 | def teamComparison(self): 56 | # print("-----") 57 | # print("Sport :",self.sportName) 58 | # print("Site 1: ",self.site1, "| Team Name: ",self.team1, "| Odds: ",self.betOdds1) 59 | # print("Site 2: ",self.site2, "| Team Name: ",self.team2, "| Odds: ",self.betOdds2) 60 | # print("-----") 61 | self.emailMessage+="======\n" 62 | self.emailMessage+="Implied Probability: {}\n".format(self.impProb) 63 | self.emailMessage+="-----\n" 64 | self.emailMessage+="Sport : {}\n".format(self.sportName) 65 | self.emailMessage+="Site 1: {} | Team Name: {} | Odds: {}\n".format(self.site1, self.team1, self.betOdds1) 66 | self.emailMessage+="Site 2: {} | Team Name: {} | Odds: {}\n".format(self.site2, self.team2, self.betOdds2) 67 | self.emailMessage+="-----\n" 68 | 69 | def emailUser(self): 70 | server = smtplib.SMTP_SSL("smtp.gmail.com", 465) 71 | server.login("WiseBetz100@gmail.com", "wrpierwlyhfdeujv") 72 | server.sendmail("WiseBetz100@gmail.com", 73 | "ReceiverOfGoodNews@gmail.com", 74 | self.emailMessage) 75 | server.quit() 76 | 77 | # Converts american odds to decimal odds 78 | def toDecimal(self, american_odds): 79 | if(american_odds<0): 80 | return (100/abs(american_odds))+1 81 | else: 82 | return (american_odds/100)+1 83 | 84 | # Converts both odds to implied probability (arbitrage is less than 100% or 1) 85 | def impliedProbability(self, odds1, odds2): 86 | return (1/self.toDecimal(odds1))+(1/self.toDecimal(odds2)) 87 | 88 | 89 | # Determins if 2 odds have Arbitrage and if so, returns true. This method also prints out arbitrage information to the user 90 | def isArbitrage(self, odds1, odds2): 91 | self.emailMessage = "" 92 | impProb = self.impliedProbability(odds1, odds2) 93 | wasEmailed = False 94 | if(impProb < 1): 95 | self.betOdds1 = odds1 96 | self.betOdds2 = odds2 97 | self.site1 = self.grid[0][self.index1] 98 | self.site2 = self.grid[0][self.index2] 99 | self.team1 = self.grid[self.index][0] 100 | self.team2 = self.grid[self.index+1][0] 101 | self.impProb = impProb 102 | # print("======") 103 | # print("Implied Probability is", impProb) 104 | self.teamComparison() 105 | #TODO might want to grab multiple arbitrage oportunities if you can (program doesn't do that yet) 106 | # assumed pay out is $100 107 | self.moneyRatio(odds1, odds2, 100) 108 | 109 | # print("what?") 110 | for array in self.emailMsgArray: 111 | # if(array == self.emailMessage): 112 | if(array.__eq__(self.emailMessage)): 113 | wasEmailed = True 114 | # print("wasEmailed") 115 | if(not wasEmailed): 116 | self.emailUser() 117 | # print("ok") 118 | self.emailMsgArray.append(self.emailMessage) 119 | self.emailMessage = "" #TODO make change 120 | wasEmailed = True 121 | # print(self.emailMessage) 122 | 123 | return True 124 | return False 125 | 126 | # Finds if there is arbitrage in the grid 127 | def anyArbitrage(self, grids): 128 | r=1 129 | x=0 130 | hasArb = False 131 | while(rlarge1): 167 | large1 = matchSet[0][i] 168 | self.index1 = i 169 | # Finds the largest value for the second set 170 | large2 = -100000 171 | for i in range(len(matchSet[1])): 172 | if(matchSet[1][i] != None): 173 | if(matchSet[1][i]>large2): 174 | large2 = matchSet[1][i] 175 | self.index2 = i 176 | # Calls the is arbitrage function to see if the two largest numbers are arbitrage 177 | return self.isArbitrage(large1,large2) 178 | 179 | # Finds out how much money should be put down (with the assuming price of total money put down) along with the ratio (if arbitrage) 180 | def moneyRatio(self, odds1, odds2, payout): 181 | #TODO https://thearbacademy.com/arbitrage-calculation/ this website might help 182 | 183 | # Gets decimal odds to perform calcultions 184 | odd1 = self.toDecimal(odds1) 185 | odd2 = self.toDecimal(odds2) 186 | 187 | # Determins how much money to stake on both sides of the bet 188 | stake1 = (payout)/odd1 189 | stake2 = (payout)/odd2 190 | 191 | # Determins the ratio to stake on both sides of the bet 192 | ratio1 = stake1/stake2 193 | ratio2 = stake2/stake1 194 | 195 | #TODO double cheek of ratio works as intended 196 | # Prints the information to the user 197 | 198 | # print("Bet $%f" %stake1, "on", self.team1, "to win $%f" %(payout - stake1), "profit. Bet 1 needs", ratio1, "times more than Bet 2.") 199 | # print("Bet $%f" %stake2, "on", self.team2, "to win $%f" %(payout - stake2), "profit. Bet 2 needs", ratio2, "times more than Bet 1.") 200 | # print("Net profit is $", payout-stake1-stake2) 201 | # print("======") 202 | 203 | self.emailMessage+="Bet ${} on {} to win ${} profit. Bet 1 needs {} times more than Bet 2.\n".format(stake1, self.team1, (payout - stake1), ratio1) 204 | self.emailMessage+="Bet ${} on {} to win ${} profit. Bet 2 needs {} times more than Bet 2.\n".format(stake2, self.team2, (payout - stake2), ratio2) 205 | self.emailMessage+="Net profit is ${}\n".format(payout-stake1-stake2) 206 | self.emailMessage+="DISCLAIMER, if odds are heavily scewed there might be an error with the sites scraped.\n" 207 | self.emailMessage+="======\n" -------------------------------------------------------------------------------- /Debugging/OddsScrapperDebug.py: -------------------------------------------------------------------------------- 1 | import math 2 | from unittest import skip 3 | 4 | import pandas as pd 5 | from CalculationsDebug import Calculations 6 | from selenium import webdriver 7 | import chromedriver_autoinstaller 8 | 9 | # Scrapper object which makes a grid to hold the name of the players and the odds of the given matches with their 10 | # corrisponding sports books 11 | class Scraper: 12 | def __init__(self): 13 | self.grid = [[]] 14 | self.sportName = "" 15 | # self.grid.append([]) 16 | # self.grid[0].append("Players Names") 17 | # self.grid[0].append("Draft Kings") 18 | # self.grid[0].append("Caesars") 19 | # self.grid[0].append("Fanduel") 20 | 21 | # prints out the grid 22 | def printData(self): 23 | print(self.grid) 24 | 25 | #clears the content of the grid 26 | def clearData(self): 27 | self.grid = [[]] 28 | 29 | # data1 to test the calculations class 30 | def testData1(self): 31 | self.grid = [[]] 32 | self.grid[0].append("Names") 33 | self.grid[0].append("Odds") 34 | self.grid.append([]) 35 | self.grid[1].append("Heads") 36 | self.grid[1].append("+150") 37 | self.grid.append([]) 38 | self.grid[2].append("Tails") 39 | self.grid[2].append("+150") 40 | 41 | # data2 to test the calculations class 42 | def testData2(self): 43 | self.grid = [[]] 44 | self.grid[0].append("Names") 45 | self.grid[0].append("Odds") 46 | self.grid[0].append("Other Odds") 47 | self.grid.append([]) 48 | self.grid[1].append("Heads") 49 | self.grid[1].append("+150") 50 | self.grid[1].append("-100") 51 | self.grid.append([]) 52 | self.grid[2].append("Tails") 53 | self.grid[2].append("-100") 54 | self.grid[2].append("+150") 55 | 56 | # A helper method to find the index of a certain value in a list and if the value is not in the index 57 | # the method returns -1 58 | def index_of(self, val, in_list): 59 | try: 60 | return in_list.index(val) 61 | except ValueError: 62 | return -1 63 | 64 | # Finds if there is arbitrage in the grid 65 | def arbitrage(self, oldMsgArray): 66 | calc = Calculations(self.grid, self.sportName) 67 | # Sets the message array to the calculations object so it know what arbitrage calls where made 68 | calc.setEmailMsgArray(oldMsgArray) 69 | calc.print() 70 | print(calc.anyArbitrage(self.grid)) 71 | 72 | newMsgArray = calc.getEmailMsgArray() 73 | return newMsgArray 74 | 75 | 76 | # Grabs the odds using the OddsShard website (MMA ODDS) 77 | def oddsSharkMMA(self): 78 | chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 79 | # and if it doesn't exist, download it automatically, 80 | # then add chromedriver to path 81 | driver = webdriver.Chrome() 82 | 83 | self.sportName = "MMA" 84 | website = "https://www.oddsshark.com/ufc/odds" 85 | driver.get(website) 86 | 87 | # adds different betting cites to the first array 88 | books = driver.find_elements_by_xpath('//div[@class="op-block__books"]/div/a') 89 | betting_sites = [] 90 | betting_sites.append("Opening Odds") 91 | 92 | count1 = 0 93 | for book in books: 94 | if(book.get_attribute("aria-label") == book.get_attribute("aria-label").upper()): 95 | if(count1 != 0): 96 | betting_sites.append(book.get_attribute("aria-label")) 97 | else: 98 | count1+=1 99 | 100 | # gets the match participants names 101 | names = driver.find_elements_by_xpath('//div[@class="op-block__matchup-team-wrapper"]/div/a/span') 102 | name_array = [] 103 | name_array2 = [] 104 | 105 | count = 0 106 | counter = 0 107 | for name in names: 108 | if(count == 0): 109 | if(counter % 2 == 0): 110 | name1 = name.text 111 | name_array.append(name1) 112 | counter+=1 113 | else: 114 | name2 = name.text 115 | name_array2.append(name2) 116 | counter+=1 117 | count+=1 118 | else: 119 | count-=1 120 | 121 | # Getting the odds from each site and removes opening odds 122 | odds_top = driver.find_elements_by_xpath('//div[@class="op-block__cell-first-row"]/div') 123 | odds_top_list = [[]] 124 | counter = 0 125 | c = 0 126 | for top in odds_top: 127 | if(count == 0): 128 | tops = top.text 129 | odds_top_list[c].append(tops) 130 | count+=1 131 | counter+=1 132 | if(counter == len(betting_sites)): 133 | counter=0 134 | odds_top_list[c].pop(0) 135 | odds_top_list.append([]) 136 | c+=1 137 | else: 138 | count-=1 139 | 140 | odds_bottom = driver.find_elements_by_xpath('//div[@class="op-block__cell-second-row"]/div') 141 | odds_bottom_list = [[]] 142 | counter = 0 143 | c = 0 144 | for bot in odds_bottom: 145 | if(count == 0): 146 | bots = bot.text 147 | odds_bottom_list[c].append(bots) 148 | count+=1 149 | counter+=1 150 | if(counter == len(betting_sites)): 151 | counter=0 152 | odds_bottom_list[c].pop(0) 153 | odds_bottom_list.append([]) 154 | c+=1 155 | else: 156 | count-=1 157 | 158 | # Finding all the null locations (there are participants with 0 odds listed) 159 | nullls = driver.find_elements_by_xpath('//div[@class="op-block__separator odds-block__separator--right"]/following-sibling::div') 160 | null_indecies = [] 161 | counter = 0 162 | for nul in nullls: 163 | if(nul.get_attribute("class") == "op-block__row not-futures no-odds-wrapper"): 164 | null_indecies.append(math.floor(counter/2)) 165 | if(counter == len(odds_bottom_list)*2): 166 | break 167 | counter+=1 168 | 169 | # Quits the website 170 | driver.quit() 171 | 172 | count = 0 173 | for n in null_indecies: 174 | if(n < len(name_array) and n < len(name_array2)): 175 | name_array.pop(n-count) 176 | name_array2.pop(n-count) 177 | count+=1 178 | 179 | # Adding First participant to Odds 180 | i=0 181 | for array in odds_top_list: 182 | array.insert(0, name_array[i]) 183 | i+=1 184 | # Adding Second participant to Odds 185 | i=0 186 | for array in odds_bottom_list: 187 | array.insert(0, name_array2[i]) 188 | i+=1 189 | 190 | # Combining both participant and odds 191 | main_grid = [[]] 192 | i=0 193 | a=0 194 | b=0 195 | for l in range(len(odds_bottom_list)+len(odds_top_list)): 196 | if(i % 2 == 0): 197 | main_grid.append(odds_top_list[a]) 198 | a+=1 199 | else: 200 | main_grid.append(odds_bottom_list[b]) 201 | b+=1 202 | i+=1 203 | 204 | # MIGHT BE ERROR HERE IN THE FUTURE 205 | main_grid.pop(0) 206 | main_grid.pop(len(main_grid)-1) 207 | main_grid.pop(len(main_grid)-1) 208 | 209 | betting_sites.insert(0, "Participant Names") 210 | betting_sites.pop(1) 211 | main_grid.insert(0, betting_sites) 212 | # All values are now stored in a 2d array called main grid which will be assigned to the grid variable 213 | self.grid = main_grid 214 | 215 | #TODO Scrap more sites (scrape the individual sites differently) 216 | 217 | def oddsSharkNHL(self): 218 | chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 219 | # and if it doesn't exist, download it automatically, 220 | # then add chromedriver to path 221 | driver = webdriver.Chrome() 222 | 223 | self.sportName = "National Hockey League" 224 | website = "https://www.oddsshark.com/nhl/odds" 225 | driver.get(website) 226 | 227 | # adds different betting cites to the first array 228 | books = driver.find_elements_by_xpath('//div[@class="op-block__books"]/div/a') 229 | betting_sites = [] 230 | betting_sites.append("Opening Odds") 231 | 232 | count1 = 0 233 | for book in books: 234 | if(book.get_attribute("aria-label") == book.get_attribute("aria-label").upper()): 235 | if(count1 != 0): 236 | betting_sites.append(book.get_attribute("aria-label")) 237 | else: 238 | count1+=1 239 | betting_sites.pop(len(betting_sites)-1) 240 | 241 | # gets the match participants names 242 | names = driver.find_elements_by_xpath('//div[@class="op-block__matchup-team-wrapper"]/div/a/span') 243 | name_array = [] 244 | name_array2 = [] 245 | 246 | count = 0 247 | counter = 0 248 | for name in names: 249 | if(count == 0): 250 | if(counter % 2 == 0): 251 | name1 = name.text 252 | name_array.append(name1) 253 | counter+=1 254 | else: 255 | name2 = name.text 256 | name_array2.append(name2) 257 | counter+=1 258 | count+=1 259 | else: 260 | count-=1 261 | 262 | # Getting the odds from each site and removes opening odds 263 | odds_top = driver.find_elements_by_xpath('//div[@class="op-block__cell-first-row"]/div') 264 | odds_top_list = [[]] 265 | counter = 0 266 | c = 0 267 | for top in odds_top: 268 | if(count == 0): 269 | tops = top.text 270 | odds_top_list[c].append(tops) 271 | count+=1 272 | counter+=1 273 | if(counter == len(betting_sites)): 274 | counter=0 275 | odds_top_list[c].pop(0) 276 | odds_top_list.append([]) 277 | c+=1 278 | else: 279 | count-=1 280 | odds_top_list.pop() 281 | 282 | odds_bottom = driver.find_elements_by_xpath('//div[@class="op-block__cell-second-row"]/div') 283 | odds_bottom_list = [[]] 284 | counter = 0 285 | c = 0 286 | for bot in odds_bottom: 287 | if(count == 0): 288 | bots = bot.text 289 | odds_bottom_list[c].append(bots) 290 | count+=1 291 | counter+=1 292 | if(counter == len(betting_sites)): 293 | counter=0 294 | odds_bottom_list[c].pop(0) 295 | odds_bottom_list.append([]) 296 | c+=1 297 | else: 298 | count-=1 299 | odds_bottom_list.pop() 300 | 301 | # Finding all the null locations (there are participants with 0 odds listed) 302 | nullls = driver.find_elements_by_xpath('//div[@class="op-block__separator odds-block__separator--right"]/following-sibling::div') 303 | null_indecies = [] 304 | counter = 0 305 | for nul in nullls: 306 | if(nul.get_attribute("class") == "op-block__row not-futures no-odds-wrapper"): 307 | null_indecies.append(math.floor(counter/2)) 308 | if(counter == len(odds_bottom_list)*2): 309 | break 310 | counter+=1 311 | 312 | # Quits the website 313 | driver.quit() 314 | 315 | count = 0 316 | for n in null_indecies: 317 | if(n < len(name_array) and n < len(name_array2)): 318 | name_array.pop(n-count) 319 | name_array2.pop(n-count) 320 | count+=1 321 | 322 | # Adding First participant to Odds 323 | i=0 324 | for array in odds_top_list: 325 | array.insert(0, name_array[i]) 326 | i+=1 327 | # Adding Second participant to Odds 328 | i=0 329 | for array in odds_bottom_list: 330 | array.insert(0, name_array2[i]) 331 | i+=1 332 | 333 | # Combining both participant and odds 334 | main_grid = [[]] 335 | i=0 336 | a=0 337 | b=0 338 | for l in range(len(odds_bottom_list)+len(odds_top_list)): 339 | if(i % 2 == 0): 340 | main_grid.append(odds_top_list[a]) 341 | a+=1 342 | else: 343 | main_grid.append(odds_bottom_list[b]) 344 | b+=1 345 | i+=1 346 | 347 | # MIGHT BE ERROR HERE IN THE FUTURE 348 | main_grid.pop(0) 349 | 350 | betting_sites.insert(0, "Participant Names") 351 | betting_sites.pop(1) 352 | main_grid.insert(0, betting_sites) 353 | # All values are now stored in a 2d array called main grid which will be assigned to the grid variable 354 | self.grid = main_grid 355 | 356 | def oddsSharkNBA(self): 357 | chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 358 | # and if it doesn't exist, download it automatically, 359 | # then add chromedriver to path 360 | driver = webdriver.Chrome() 361 | 362 | self.sportName = "NBA" 363 | website = "https://www.oddsshark.com/nba/odds" 364 | driver.get(website) 365 | 366 | # adds different betting cites to the first array 367 | books = driver.find_elements_by_xpath('//div[@class="op-block__books"]/div/a') 368 | betting_sites = [] 369 | betting_sites.append("Opening Odds") 370 | 371 | count1 = 0 372 | for book in books: 373 | if(book.get_attribute("aria-label") == book.get_attribute("aria-label").upper()): 374 | if(count1 != 0): 375 | betting_sites.append(book.get_attribute("aria-label")) 376 | else: 377 | count1+=1 378 | betting_sites.pop(len(betting_sites)-1) 379 | 380 | # gets the match participants names 381 | names = driver.find_elements_by_xpath('//div[@class="op-block__matchup-team-wrapper"]/div/a/span') 382 | name_array = [] 383 | name_array2 = [] 384 | 385 | count = 0 386 | counter = 0 387 | for name in names: 388 | if(count == 0): 389 | if(counter % 2 == 0): 390 | name1 = name.text 391 | name_array.append(name1) 392 | counter+=1 393 | else: 394 | name2 = name.text 395 | name_array2.append(name2) 396 | counter+=1 397 | count+=1 398 | else: 399 | count-=1 400 | 401 | # Getting the odds from each site and removes opening odds 402 | odds_top = driver.find_elements_by_xpath('//div[@class="op-block__cell-first-row"]/div') 403 | odds_top_list = [[]] 404 | counter = 0 405 | c = 0 406 | for top in odds_top: 407 | if(count == 1): 408 | tops = top.text 409 | odds_top_list[c].append(tops) 410 | count-=1 411 | counter+=1 412 | if(counter == len(betting_sites)): 413 | counter=0 414 | odds_top_list[c].pop(0) 415 | odds_top_list.append([]) 416 | c+=1 417 | else: 418 | count+=1 419 | odds_top_list.pop() 420 | 421 | odds_bottom = driver.find_elements_by_xpath('//div[@class="op-block__cell-second-row"]/div') 422 | odds_bottom_list = [[]] 423 | counter = 0 424 | c = 0 425 | for bot in odds_bottom: 426 | if(count == 1): 427 | bots = bot.text 428 | odds_bottom_list[c].append(bots) 429 | count-=1 430 | counter+=1 431 | if(counter == len(betting_sites)): 432 | counter=0 433 | odds_bottom_list[c].pop(0) 434 | odds_bottom_list.append([]) 435 | c+=1 436 | else: 437 | count+=1 438 | odds_bottom_list.pop() 439 | 440 | # Finding all the null locations (there are participants with 0 odds listed) 441 | nullls = driver.find_elements_by_xpath('//div[@class="op-block__separator odds-block__separator--right"]/following-sibling::div') 442 | null_indecies = [] 443 | counter = 0 444 | for nul in nullls: 445 | if(nul.get_attribute("class") == "op-block__row not-futures no-odds-wrapper"): 446 | null_indecies.append(math.floor(counter/2)) 447 | if(counter == len(odds_bottom_list)*2): 448 | break 449 | counter+=1 450 | 451 | # Quits the website 452 | driver.quit() 453 | 454 | count = 0 455 | for n in null_indecies: 456 | if(n < len(name_array) and n < len(name_array2)): 457 | name_array.pop(n-count) 458 | name_array2.pop(n-count) 459 | count+=1 460 | 461 | # Adding First participant to Odds 462 | i=0 463 | for array in odds_top_list: 464 | array.insert(0, name_array[i]) 465 | i+=1 466 | # Adding Second participant to Odds 467 | i=0 468 | for array in odds_bottom_list: 469 | array.insert(0, name_array2[i]) 470 | i+=1 471 | 472 | # Combining both participant and odds 473 | main_grid = [[]] 474 | i=0 475 | a=0 476 | b=0 477 | for l in range(len(odds_bottom_list)+len(odds_top_list)): 478 | if(i % 2 == 0): 479 | main_grid.append(odds_top_list[a]) 480 | a+=1 481 | else: 482 | main_grid.append(odds_bottom_list[b]) 483 | b+=1 484 | i+=1 485 | 486 | # MIGHT BE ERROR HERE IN THE FUTURE 487 | main_grid.pop(0) 488 | 489 | betting_sites.insert(0, "Participant Names") 490 | betting_sites.pop(1) 491 | main_grid.insert(0, betting_sites) 492 | # All values are now stored in a 2d array called main grid which will be assigned to the grid variable 493 | self.grid = main_grid 494 | 495 | def oddsSharkMLB(self): 496 | chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 497 | # and if it doesn't exist, download it automatically, 498 | # then add chromedriver to path 499 | driver = webdriver.Chrome() 500 | 501 | self.sportName = "Major League Baseball" 502 | website = "https://www.oddsshark.com/mlb/odds" 503 | driver.get(website) 504 | 505 | # adds different betting cites to the first array 506 | books = driver.find_elements_by_xpath('//div[@class="op-block__books"]/div/a') 507 | betting_sites = [] 508 | betting_sites.append("Opening Odds") 509 | 510 | count1 = 0 511 | for book in books: 512 | if(book.get_attribute("aria-label") == book.get_attribute("aria-label").upper()): 513 | if(count1 != 0): 514 | betting_sites.append(book.get_attribute("aria-label")) 515 | else: 516 | count1+=1 517 | 518 | # gets the match participants names 519 | names = driver.find_elements_by_xpath('//div[@class="op-block__matchup-team-wrapper"]/div/a/span') 520 | name_array = [] 521 | name_array2 = [] 522 | 523 | count = 0 524 | counter = 0 525 | for name in names: 526 | if(count == 0): 527 | if(counter % 2 == 0): 528 | name1 = name.text 529 | name_array.append(name1) 530 | counter+=1 531 | else: 532 | name2 = name.text 533 | name_array2.append(name2) 534 | counter+=1 535 | count+=1 536 | else: 537 | count-=1 538 | 539 | # Getting the odds from each site and removes opening odds 540 | odds_top = driver.find_elements_by_xpath('//div[@class="op-block__cell-first-row"]/div') 541 | odds_top_list = [[]] 542 | counter = 0 543 | c = 0 544 | for top in odds_top: 545 | if(count == 0): 546 | tops = top.text 547 | odds_top_list[c].append(tops) 548 | count+=1 549 | counter+=1 550 | if(counter == len(betting_sites)): 551 | counter=0 552 | odds_top_list[c].pop(0) 553 | odds_top_list.append([]) 554 | c+=1 555 | else: 556 | count-=1 557 | odds_top_list.pop() 558 | 559 | odds_bottom = driver.find_elements_by_xpath('//div[@class="op-block__cell-second-row"]/div') 560 | odds_bottom_list = [[]] 561 | counter = 0 562 | c = 0 563 | for bot in odds_bottom: 564 | if(count == 0): 565 | bots = bot.text 566 | odds_bottom_list[c].append(bots) 567 | count+=1 568 | counter+=1 569 | if(counter == len(betting_sites)): 570 | counter=0 571 | odds_bottom_list[c].pop(0) 572 | odds_bottom_list.append([]) 573 | c+=1 574 | else: 575 | count-=1 576 | odds_bottom_list.pop() 577 | 578 | # Finding all the null locations (there are participants with 0 odds listed) 579 | nullls = driver.find_elements_by_xpath('//div[@class="op-block__separator odds-block__separator--right"]/following-sibling::div') 580 | null_indecies = [] 581 | counter = 0 582 | for nul in nullls: 583 | if(nul.get_attribute("class") == "op-block__row not-futures no-odds-wrapper"): 584 | null_indecies.append(math.floor(counter/2)) 585 | if(counter == len(odds_bottom_list)*2): 586 | break 587 | counter+=1 588 | 589 | # Quits the website 590 | driver.quit() 591 | 592 | count = 0 593 | for n in null_indecies: 594 | if(n < len(name_array) and n < len(name_array2)): 595 | name_array.pop(n-count) 596 | name_array2.pop(n-count) 597 | count+=1 598 | 599 | # Adding First participant to Odds 600 | i=0 601 | for array in odds_top_list: 602 | array.insert(0, name_array[i]) 603 | i+=1 604 | # Adding Second participant to Odds 605 | i=0 606 | for array in odds_bottom_list: 607 | array.insert(0, name_array2[i]) 608 | i+=1 609 | 610 | # Combining both participant and odds 611 | main_grid = [[]] 612 | i=0 613 | a=0 614 | b=0 615 | for l in range(len(odds_bottom_list)+len(odds_top_list)): 616 | if(i % 2 == 0): 617 | main_grid.append(odds_top_list[a]) 618 | a+=1 619 | else: 620 | main_grid.append(odds_bottom_list[b]) 621 | b+=1 622 | i+=1 623 | 624 | # MIGHT BE ERROR HERE IN THE FUTURE 625 | main_grid.pop(0) 626 | 627 | betting_sites.insert(0, "Participant Names") 628 | betting_sites.pop(1) 629 | main_grid.insert(0, betting_sites) 630 | # All values are now stored in a 2d array called main grid which will be assigned to the grid variable 631 | self.grid = main_grid 632 | 633 | 634 | 635 | 636 | 637 | #------------------------------------------------------------------------------------------ 638 | #TODO EVERYTHING PAST THIS POINT IS EXPIRIMENTAL AND DOESN'T WORK AS INTENDED 639 | # def draftKingsMMA(self): 640 | # chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 641 | # # and if it doesn't exist, download it automatically, 642 | # # then add chromedriver to path 643 | # driver = webdriver.Chrome() 644 | 645 | # website = "https://sportsbook.draftkings.com/leagues/mma/88670562" 646 | # driver.get(website) 647 | 648 | # # Name of team/player 649 | # names = driver.find_elements_by_xpath('//div[@class="sportsbook-outcome-body-wrapper"]/div/span') 650 | # nameArr = [] 651 | # for name in names: 652 | # nameArr.append(name.text) 653 | 654 | # # Odds of team/player 655 | # odds = driver.find_elements_by_xpath('//div[@class="sportsbook-outcome-body-wrapper"]/div/div/span') 656 | # oddsArr = [] 657 | # for odd in odds: 658 | # oddsArr.append(odd.text) 659 | 660 | # # Checks if the name is in the grid and if it's not, add it along with odds. 661 | # for i in range(len(nameArr)): 662 | # # Checks if the name is in the not in the grid and adds the odds. 663 | # if(not any(nameArr[i] in sublist for sublist in self.grid)): 664 | # self.grid.append([]) 665 | # self.grid[len(self.grid)-1].append(nameArr[i]) 666 | # self.grid[len(self.grid)-1].append(oddsArr[i]) 667 | # else: 668 | # # Adds the odds to the given player array if the player exsists on that array 669 | # for j in range(len(self.grid)): 670 | # if(self.index_of(nameArr[i], self.grid[j]) != -1): 671 | # self.grid[j].append(oddsArr[i]) 672 | # # adds '' to names which are not touched by this method 673 | # for i in range(len(self.grid)): 674 | # if(len(self.grid[i]) < 2): 675 | # self.grid[i].append(''); 676 | # # print(self.grid) 677 | # driver.close() 678 | 679 | # def CaesarsMMA(self): 680 | # chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 681 | # # and if it doesn't exist, download it automatically, 682 | # # then add chromedriver to path 683 | # driver = webdriver.Chrome() 684 | 685 | # website = "https://www.williamhill.com/us/co/bet/ufcmma" 686 | # driver.get(website) 687 | 688 | # # Name of team/player 689 | # names = driver.find_elements_by_xpath('//div[@class="teamLabel maxIOSHeight"]/span') 690 | # nameArr = [] 691 | # #TODO not gathering all names 692 | # for name in names: 693 | # nameArr.append(name.text) 694 | # # print(nameArr) 695 | 696 | # #TODO not gathering all odds 697 | # # Odds of team/player 698 | # odds = driver.find_elements_by_xpath('//div[@class="oddsView"]/div') 699 | # oddsArr = [] 700 | # count = 0 701 | # for odd in odds: 702 | # # print(odd.text) 703 | # if (count > 1): 704 | # oddsArr.append(odd.text) 705 | # count+=1 706 | 707 | # # print(oddsArr) 708 | 709 | # # print(self.grid) 710 | # # Checks if the name is in the grid and if it's not, add it along with odds. 711 | # for i in range(len(nameArr)): 712 | # # Checks if the name is in the not in the grid and adds the odds. 713 | # if(not any(nameArr[i] in sublist for sublist in self.grid)): 714 | # #TODO this could be wrong 715 | # self.grid.append([]) 716 | # self.grid[len(self.grid)-1].append(nameArr[i]) 717 | # # Adds a none because Draft kings doesn't have a list if this is checked 718 | # self.grid[len(self.grid)-1].append('') 719 | # self.grid[len(self.grid)-1].append(oddsArr[i]) 720 | # else: 721 | # # Adds the odds to the given player array if the player exsists on that array 722 | # for j in range(len(self.grid)): 723 | # if(self.index_of(nameArr[i], self.grid[j]) != -1): 724 | # self.grid[j].append(oddsArr[i]) 725 | # # adds '' to names which are not touched by this method 726 | # for i in range(len(self.grid)): 727 | # # if(len(self.grid[i]) < len(self.grid[0])): 728 | # if(len(self.grid[i]) < 3): 729 | # self.grid[i].append(''); 730 | 731 | # # print(self.grid) 732 | # driver.close() 733 | 734 | # def FanduelMMA(self): 735 | # # chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 736 | # # # and if it doesn't exist, download it automatically, 737 | # # # then add chromedriver to path 738 | # # driver = webdriver.Chrome() 739 | 740 | # website = "https://nj.pointsbet.com/sports/mma/UFC" 741 | # self.driver.get(website) 742 | 743 | # # Name of team/player 744 | # # names = driver.find_elements_by_xpath('//span[@class="ae aj iu iv iw ix ij ik il io iy s gd dw iz h i j ak l m al o am q an br"]') 745 | # names = self.driver.find_elements_by_xpath('//span[@class="f1fdaby6"]') 746 | # nameArr = [] 747 | # print("sad") 748 | # for name in names: 749 | # print(name.text) 750 | # nameArr.append(name.text) 751 | 752 | # # Odds of team/player 753 | # odds = self.driver.find_elements_by_xpath('//span[@class="fheif50"]') 754 | # oddsArr = [] 755 | # for odd in odds: 756 | # print(odd.text) 757 | # oddsArr.append(odd.text) 758 | 759 | # # Checks if the name is in the grid and if it's not, add it along with odds. 760 | # for i in range(len(nameArr)): 761 | # # Checks if the name is in the not in the grid and adds the odds. 762 | # if(not any(nameArr[i] in sublist for sublist in self.grid)): 763 | # self.grid.append([]) 764 | # self.grid[len(self.grid)-1].append(nameArr[i]) 765 | # self.grid[len(self.grid)-1].append(oddsArr[i]) 766 | # else: 767 | # # Adds the odds to the given player array if the player exsists on that array 768 | # for j in range(len(self.grid)): 769 | # if(self.index_of(nameArr[i], self.grid[j]) != -1): 770 | # self.grid[j].append(oddsArr[i]) 771 | # # adds '' to names which are not touched by this method 772 | # for i in range(len(self.grid)): 773 | # # The integer number should change with the position which the code is being declaired 774 | # if(len(self.grid[i]) < 4): 775 | # self.grid[i].append(''); 776 | # # self.grid[i].append(''); 777 | # # print(self.grid) 778 | # self.driver.close() -------------------------------------------------------------------------------- /OddsScrapper.py: -------------------------------------------------------------------------------- 1 | import math 2 | from unittest import skip 3 | 4 | import pandas as pd 5 | import time 6 | from Calculations import Calculations 7 | from selenium import webdriver 8 | import chromedriver_autoinstaller 9 | from selenium.webdriver.chrome.options import Options 10 | 11 | # https://www.guru99.com/xpath-selenium.html help for writing certain xpaths 12 | 13 | # Scrapper object which makes a grid to hold the name of the players and the odds of the given matches with their 14 | # corrisponding sports books 15 | class Scraper: 16 | def __init__(self): 17 | self.grid = [[]] 18 | self.sportName = "" 19 | # self.grid.append([]) 20 | self.grid[0].append("Players Names") 21 | # self.grid[0].append("Draft Kings") 22 | # self.grid[0].append("Caesars") 23 | self.options = Options() 24 | # self.grid[0].append("Fanduel") 25 | 26 | # prints out the grid 27 | def printData(self): 28 | print(self.grid) 29 | 30 | #clears the content of the grid 31 | def clearData(self): 32 | self.grid = [[]] 33 | 34 | # data1 to test the calculations class 35 | def testData1(self): 36 | self.grid = [[]] 37 | self.grid[0].append("Names") 38 | self.grid[0].append("Odds") 39 | self.grid.append([]) 40 | self.grid[1].append("Heads") 41 | self.grid[1].append("+150") 42 | self.grid.append([]) 43 | self.grid[2].append("Tails") 44 | self.grid[2].append("+150") 45 | 46 | # data2 to test the calculations class 47 | def testData2(self): 48 | self.grid = [[]] 49 | self.grid[0].append("Names") 50 | self.grid[0].append("Odds") 51 | self.grid[0].append("Other Odds") 52 | self.grid.append([]) 53 | self.grid[1].append("Heads") 54 | self.grid[1].append("+150") 55 | self.grid[1].append("-100") 56 | self.grid.append([]) 57 | self.grid[2].append("Tails") 58 | self.grid[2].append("-100") 59 | self.grid[2].append("+150") 60 | print("running") 61 | 62 | # A helper method to find the index of a certain value in a list and if the value is not in the index 63 | # the method returns -1 64 | def index_of(self, val, in_list): 65 | try: 66 | return in_list.index(val) 67 | except ValueError: 68 | return -1 69 | 70 | # Finds if there is arbitrage in the grid 71 | def arbitrage(self, oldMsgArray): 72 | calc = Calculations(self.grid, self.sportName) 73 | # Sets the message array to the calculations object so it know what arbitrage calls where made 74 | calc.setEmailMsgArray(oldMsgArray) 75 | calc.print() 76 | print(calc.anyArbitrage(self.grid)) 77 | 78 | newMsgArray = calc.getEmailMsgArray() 79 | return newMsgArray 80 | 81 | 82 | # Grabs the odds using the OddsShard website (MMA ODDS) 83 | def oddsSharkMMA(self): 84 | chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 85 | # and if it doesn't exist, download it automatically, 86 | # then add chromedriver to path 87 | driver = webdriver.Chrome() 88 | 89 | self.sportName = "MMA" 90 | website = "https://www.oddsshark.com/ufc/odds" 91 | driver.get(website) 92 | 93 | # adds different betting cites to the first array 94 | books = driver.find_elements_by_xpath('//div[@class="op-block__books"]/div/a') 95 | betting_sites = [] 96 | betting_sites.append("Opening Odds") 97 | 98 | count1 = 0 99 | for book in books: 100 | if(book.get_attribute("aria-label") == book.get_attribute("aria-label").upper()): 101 | if(count1 != 0): 102 | betting_sites.append(book.get_attribute("aria-label")) 103 | else: 104 | count1+=1 105 | 106 | # gets the match participants names 107 | names = driver.find_elements_by_xpath('//div[@class="op-block__matchup-team-wrapper"]/div/a/span') 108 | name_array = [] 109 | name_array2 = [] 110 | 111 | count = 0 112 | counter = 0 113 | for name in names: 114 | if(count == 0): 115 | if(counter % 2 == 0): 116 | name1 = name.text 117 | name_array.append(name1) 118 | counter+=1 119 | else: 120 | name2 = name.text 121 | name_array2.append(name2) 122 | counter+=1 123 | count+=1 124 | else: 125 | count-=1 126 | 127 | # Getting the odds from each site and removes opening odds 128 | odds_top = driver.find_elements_by_xpath('//*[contains(@class,"op-block__cell-first-row")]/div') 129 | # //div[@class="op-block__cell-first-row"]/div 130 | odds_top_list = [[]] 131 | counter = 0 132 | c = 0 133 | for top in odds_top: 134 | if(count == 0): 135 | tops = top.text 136 | odds_top_list[c].append(tops) 137 | count+=1 138 | counter+=1 139 | if(counter == len(betting_sites)): 140 | counter=0 141 | odds_top_list[c].pop(0) 142 | odds_top_list.append([]) 143 | c+=1 144 | else: 145 | count-=1 146 | 147 | odds_bottom = driver.find_elements_by_xpath('//*[contains(@class,"op-block__cell-second-row")]/div') 148 | # //div[@class="op-block__cell-second-row"]/div 149 | odds_bottom_list = [[]] 150 | counter = 0 151 | c = 0 152 | for bot in odds_bottom: 153 | if(count == 0): 154 | bots = bot.text 155 | odds_bottom_list[c].append(bots) 156 | count+=1 157 | counter+=1 158 | if(counter == len(betting_sites)): 159 | counter=0 160 | odds_bottom_list[c].pop(0) 161 | odds_bottom_list.append([]) 162 | c+=1 163 | else: 164 | count-=1 165 | 166 | # Finding all the null locations (there are participants with 0 odds listed) 167 | nullls = driver.find_elements_by_xpath('//div[@class="op-block__separator odds-block__separator--right"]/following-sibling::div') 168 | null_indecies = [] 169 | counter = 0 170 | for nul in nullls: 171 | if(nul.get_attribute("class") == "op-block__row not-futures no-odds-wrapper"): 172 | null_indecies.append(math.floor(counter/2)) 173 | if(counter == len(odds_bottom_list)*2): 174 | break 175 | counter+=1 176 | 177 | # Quits the website 178 | driver.quit() 179 | 180 | count = 0 181 | for n in null_indecies: 182 | if(n < len(name_array) and n < len(name_array2)): 183 | name_array.pop(n-count) 184 | name_array2.pop(n-count) 185 | count+=1 186 | 187 | # Adding First participant to Odds 188 | i=0 189 | for array in odds_top_list: 190 | array.insert(0, name_array[i]) 191 | i+=1 192 | # Adding Second participant to Odds 193 | i=0 194 | for array in odds_bottom_list: 195 | array.insert(0, name_array2[i]) 196 | i+=1 197 | 198 | # Combining both participant and odds 199 | main_grid = [[]] 200 | i=0 201 | a=0 202 | b=0 203 | for l in range(len(odds_bottom_list)+len(odds_top_list)): 204 | if(i % 2 == 0): 205 | main_grid.append(odds_top_list[a]) 206 | a+=1 207 | else: 208 | main_grid.append(odds_bottom_list[b]) 209 | b+=1 210 | i+=1 211 | 212 | # MIGHT BE ERROR HERE IN THE FUTURE 213 | main_grid.pop(0) 214 | main_grid.pop(len(main_grid)-1) 215 | main_grid.pop(len(main_grid)-1) 216 | 217 | betting_sites.insert(0, "Participant Names") 218 | betting_sites.pop(1) 219 | main_grid.insert(0, betting_sites) 220 | # All values are now stored in a 2d array called main grid which will be assigned to the grid variable 221 | self.grid = main_grid 222 | 223 | #TODO Scrap more sites (scrape the individual sites differently) 224 | 225 | def oddsSharkNHL(self): 226 | chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 227 | # and if it doesn't exist, download it automatically, 228 | # then add chromedriver to path 229 | driver = webdriver.Chrome() 230 | 231 | self.sportName = "National Hockey League" 232 | website = "https://www.oddsshark.com/nhl/odds" 233 | driver.get(website) 234 | 235 | # adds different betting cites to the first array 236 | books = driver.find_elements_by_xpath('//div[@class="op-block__books"]/div/a') 237 | betting_sites = [] 238 | betting_sites.append("Opening Odds") 239 | 240 | count1 = 0 241 | for book in books: 242 | if(book.get_attribute("aria-label") == book.get_attribute("aria-label").upper()): 243 | if(count1 != 0): 244 | betting_sites.append(book.get_attribute("aria-label")) 245 | else: 246 | count1+=1 247 | betting_sites.pop(len(betting_sites)-1) 248 | 249 | # gets the match participants names 250 | names = driver.find_elements_by_xpath('//div[@class="op-block__matchup-team-wrapper"]/div/a/span') 251 | name_array = [] 252 | name_array2 = [] 253 | 254 | count = 0 255 | counter = 0 256 | for name in names: 257 | if(count == 0): 258 | if(counter % 2 == 0): 259 | name1 = name.text 260 | name_array.append(name1) 261 | counter+=1 262 | else: 263 | name2 = name.text 264 | name_array2.append(name2) 265 | counter+=1 266 | count+=1 267 | else: 268 | count-=1 269 | 270 | # Getting the odds from each site and removes opening odds 271 | odds_top = driver.find_elements_by_xpath('//div[@class="op-block__cell-first-row"]/div') 272 | odds_top_list = [[]] 273 | counter = 0 274 | c = 0 275 | for top in odds_top: 276 | if(count == 0): 277 | tops = top.text 278 | odds_top_list[c].append(tops) 279 | count+=1 280 | counter+=1 281 | if(counter == len(betting_sites)): 282 | counter=0 283 | odds_top_list[c].pop(0) 284 | odds_top_list.append([]) 285 | c+=1 286 | else: 287 | count-=1 288 | odds_top_list.pop() 289 | 290 | odds_bottom = driver.find_elements_by_xpath('//div[@class="op-block__cell-second-row"]/div') 291 | odds_bottom_list = [[]] 292 | counter = 0 293 | c = 0 294 | for bot in odds_bottom: 295 | if(count == 0): 296 | bots = bot.text 297 | odds_bottom_list[c].append(bots) 298 | count+=1 299 | counter+=1 300 | if(counter == len(betting_sites)): 301 | counter=0 302 | odds_bottom_list[c].pop(0) 303 | odds_bottom_list.append([]) 304 | c+=1 305 | else: 306 | count-=1 307 | odds_bottom_list.pop() 308 | 309 | # Finding all the null locations (there are participants with 0 odds listed) 310 | nullls = driver.find_elements_by_xpath('//div[@class="op-block__separator odds-block__separator--right"]/following-sibling::div') 311 | null_indecies = [] 312 | counter = 0 313 | for nul in nullls: 314 | if(nul.get_attribute("class") == "op-block__row not-futures no-odds-wrapper"): 315 | null_indecies.append(math.floor(counter/2)) 316 | if(counter == len(odds_bottom_list)*2): 317 | break 318 | counter+=1 319 | 320 | # Quits the website 321 | driver.quit() 322 | 323 | count = 0 324 | for n in null_indecies: 325 | if(n < len(name_array) and n < len(name_array2)): 326 | name_array.pop(n-count) 327 | name_array2.pop(n-count) 328 | count+=1 329 | 330 | # Adding First participant to Odds 331 | i=0 332 | for array in odds_top_list: 333 | array.insert(0, name_array[i]) 334 | i+=1 335 | # Adding Second participant to Odds 336 | i=0 337 | for array in odds_bottom_list: 338 | array.insert(0, name_array2[i]) 339 | i+=1 340 | 341 | # Combining both participant and odds 342 | main_grid = [[]] 343 | i=0 344 | a=0 345 | b=0 346 | for l in range(len(odds_bottom_list)+len(odds_top_list)): 347 | if(i % 2 == 0): 348 | main_grid.append(odds_top_list[a]) 349 | a+=1 350 | else: 351 | main_grid.append(odds_bottom_list[b]) 352 | b+=1 353 | i+=1 354 | 355 | # MIGHT BE ERROR HERE IN THE FUTURE 356 | main_grid.pop(0) 357 | 358 | betting_sites.insert(0, "Participant Names") 359 | betting_sites.pop(1) 360 | main_grid.insert(0, betting_sites) 361 | # All values are now stored in a 2d array called main grid which will be assigned to the grid variable 362 | self.grid = main_grid 363 | 364 | def oddsSharkNBA(self): 365 | chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 366 | # and if it doesn't exist, download it automatically, 367 | # then add chromedriver to path 368 | driver = webdriver.Chrome() 369 | 370 | self.sportName = "NBA" 371 | website = "https://www.oddsshark.com/nba/odds" 372 | driver.get(website) 373 | 374 | # adds different betting cites to the first array 375 | books = driver.find_elements_by_xpath('//div[@class="op-block__books"]/div/a') 376 | betting_sites = [] 377 | betting_sites.append("Opening Odds") 378 | 379 | count1 = 0 380 | for book in books: 381 | if(book.get_attribute("aria-label") == book.get_attribute("aria-label").upper()): 382 | if(count1 != 0): 383 | betting_sites.append(book.get_attribute("aria-label")) 384 | else: 385 | count1+=1 386 | betting_sites.pop(len(betting_sites)-1) 387 | 388 | # gets the match participants names 389 | names = driver.find_elements_by_xpath('//div[@class="op-block__matchup-team-wrapper"]/div/a/span') 390 | name_array = [] 391 | name_array2 = [] 392 | 393 | count = 0 394 | counter = 0 395 | for name in names: 396 | if(count == 0): 397 | if(counter % 2 == 0): 398 | name1 = name.text 399 | name_array.append(name1) 400 | counter+=1 401 | else: 402 | name2 = name.text 403 | name_array2.append(name2) 404 | counter+=1 405 | count+=1 406 | else: 407 | count-=1 408 | 409 | # Getting the odds from each site and removes opening odds 410 | odds_top = driver.find_elements_by_xpath('//div[@class="op-block__cell-first-row"]/div') 411 | odds_top_list = [[]] 412 | counter = 0 413 | c = 0 414 | for top in odds_top: 415 | if(count == 1): 416 | tops = top.text 417 | odds_top_list[c].append(tops) 418 | count-=1 419 | counter+=1 420 | if(counter == len(betting_sites)): 421 | counter=0 422 | odds_top_list[c].pop(0) 423 | odds_top_list.append([]) 424 | c+=1 425 | else: 426 | count+=1 427 | odds_top_list.pop() 428 | 429 | odds_bottom = driver.find_elements_by_xpath('//div[@class="op-block__cell-second-row"]/div') 430 | odds_bottom_list = [[]] 431 | counter = 0 432 | c = 0 433 | for bot in odds_bottom: 434 | if(count == 1): 435 | bots = bot.text 436 | odds_bottom_list[c].append(bots) 437 | count-=1 438 | counter+=1 439 | if(counter == len(betting_sites)): 440 | counter=0 441 | odds_bottom_list[c].pop(0) 442 | odds_bottom_list.append([]) 443 | c+=1 444 | else: 445 | count+=1 446 | odds_bottom_list.pop() 447 | 448 | # Finding all the null locations (there are participants with 0 odds listed) 449 | nullls = driver.find_elements_by_xpath('//div[@class="op-block__separator odds-block__separator--right"]/following-sibling::div') 450 | null_indecies = [] 451 | counter = 0 452 | for nul in nullls: 453 | if(nul.get_attribute("class") == "op-block__row not-futures no-odds-wrapper"): 454 | null_indecies.append(math.floor(counter/2)) 455 | if(counter == len(odds_bottom_list)*2): 456 | break 457 | counter+=1 458 | 459 | # Quits the website 460 | driver.quit() 461 | 462 | count = 0 463 | for n in null_indecies: 464 | if(n < len(name_array) and n < len(name_array2)): 465 | name_array.pop(n-count) 466 | name_array2.pop(n-count) 467 | count+=1 468 | 469 | # Adding First participant to Odds 470 | i=0 471 | for array in odds_top_list: 472 | array.insert(0, name_array[i]) 473 | i+=1 474 | # Adding Second participant to Odds 475 | i=0 476 | for array in odds_bottom_list: 477 | array.insert(0, name_array2[i]) 478 | i+=1 479 | 480 | # Combining both participant and odds 481 | main_grid = [[]] 482 | i=0 483 | a=0 484 | b=0 485 | for l in range(len(odds_bottom_list)+len(odds_top_list)): 486 | if(i % 2 == 0): 487 | main_grid.append(odds_top_list[a]) 488 | a+=1 489 | else: 490 | main_grid.append(odds_bottom_list[b]) 491 | b+=1 492 | i+=1 493 | 494 | # MIGHT BE ERROR HERE IN THE FUTURE 495 | main_grid.pop(0) 496 | 497 | betting_sites.insert(0, "Participant Names") 498 | betting_sites.pop(1) 499 | main_grid.insert(0, betting_sites) 500 | # All values are now stored in a 2d array called main grid which will be assigned to the grid variable 501 | self.grid = main_grid 502 | 503 | def oddsSharkMLB(self): 504 | chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 505 | # and if it doesn't exist, download it automatically, 506 | # then add chromedriver to path 507 | driver = webdriver.Chrome() 508 | 509 | self.sportName = "Major League Baseball" 510 | website = "https://www.oddsshark.com/mlb/odds" 511 | driver.get(website) 512 | 513 | # adds different betting cites to the first array 514 | books = driver.find_elements_by_xpath('//div[@class="op-block__books"]/div/a') 515 | betting_sites = [] 516 | betting_sites.append("Opening Odds") 517 | 518 | count1 = 0 519 | for book in books: 520 | if(book.get_attribute("aria-label") == book.get_attribute("aria-label").upper()): 521 | if(count1 != 0): 522 | betting_sites.append(book.get_attribute("aria-label")) 523 | else: 524 | count1+=1 525 | 526 | # gets the match participants names 527 | names = driver.find_elements_by_xpath('//div[@class="op-block__matchup-team-wrapper"]/div/a/span') 528 | name_array = [] 529 | name_array2 = [] 530 | 531 | count = 0 532 | counter = 0 533 | for name in names: 534 | if(count == 0): 535 | if(counter % 2 == 0): 536 | name1 = name.text 537 | name_array.append(name1) 538 | counter+=1 539 | else: 540 | name2 = name.text 541 | name_array2.append(name2) 542 | counter+=1 543 | count+=1 544 | else: 545 | count-=1 546 | 547 | # Getting the odds from each site and removes opening odds 548 | odds_top = driver.find_elements_by_xpath('//*[contains(@class,"op-block__cell-first-row")]/div') 549 | odds_top_list = [[]] 550 | counter = 0 551 | c = 0 552 | for top in odds_top: 553 | if(count == 0): 554 | tops = top.text 555 | odds_top_list[c].append(tops) 556 | count+=1 557 | counter+=1 558 | if(counter == len(betting_sites)): 559 | counter=0 560 | odds_top_list[c].pop(0) 561 | odds_top_list.append([]) 562 | c+=1 563 | else: 564 | count-=1 565 | odds_top_list.pop() 566 | 567 | odds_bottom = driver.find_elements_by_xpath('//*[contains(@class,"op-block__cell-second-row")]/div') 568 | odds_bottom_list = [[]] 569 | counter = 0 570 | c = 0 571 | for bot in odds_bottom: 572 | if(count == 0): 573 | bots = bot.text 574 | odds_bottom_list[c].append(bots) 575 | count+=1 576 | counter+=1 577 | if(counter == len(betting_sites)): 578 | counter=0 579 | odds_bottom_list[c].pop(0) 580 | odds_bottom_list.append([]) 581 | c+=1 582 | else: 583 | count-=1 584 | odds_bottom_list.pop() 585 | 586 | # Finding all the null locations (there are participants with 0 odds listed) 587 | nullls = driver.find_elements_by_xpath('//div[@class="op-block__separator odds-block__separator--right"]/following-sibling::div') 588 | null_indecies = [] 589 | counter = 0 590 | for nul in nullls: 591 | if(nul.get_attribute("class") == "op-block__row not-futures no-odds-wrapper"): 592 | null_indecies.append(math.floor(counter/2)) 593 | if(counter == len(odds_bottom_list)*2): 594 | break 595 | counter+=1 596 | 597 | # Quits the website 598 | driver.quit() 599 | 600 | count = 0 601 | for n in null_indecies: 602 | if(n < len(name_array) and n < len(name_array2)): 603 | name_array.pop(n-count) 604 | name_array2.pop(n-count) 605 | count+=1 606 | 607 | # Adding First participant to Odds 608 | i=0 609 | for array in odds_top_list: 610 | array.insert(0, name_array[i]) 611 | i+=1 612 | # Adding Second participant to Odds 613 | i=0 614 | for array in odds_bottom_list: 615 | array.insert(0, name_array2[i]) 616 | i+=1 617 | 618 | # Combining both participant and odds 619 | main_grid = [[]] 620 | i=0 621 | a=0 622 | b=0 623 | for l in range(len(odds_bottom_list)+len(odds_top_list)): 624 | if(i % 2 == 0): 625 | main_grid.append(odds_top_list[a]) 626 | a+=1 627 | else: 628 | main_grid.append(odds_bottom_list[b]) 629 | b+=1 630 | i+=1 631 | 632 | # MIGHT BE ERROR HERE IN THE FUTURE 633 | main_grid.pop(0) 634 | 635 | betting_sites.insert(0, "Participant Names") 636 | betting_sites.pop(1) 637 | main_grid.insert(0, betting_sites) 638 | # All values are now stored in a 2d array called main grid which will be assigned to the grid variable 639 | self.grid = main_grid 640 | 641 | #TODO ADD NCAAF BETTING LINES (COLLEGE FOOTBALL) 642 | #TODO NEEDS TO BE UPDATED FOR NCAFF NAMES 643 | def oddsSharkNCAAF(self): 644 | chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 645 | # and if it doesn't exist, download it automatically, 646 | # then add chromedriver to path 647 | driver = webdriver.Chrome() 648 | 649 | self.sportName = "College Football" 650 | website = "https://www.oddsshark.com/ncaaf/odds" 651 | driver.get(website) 652 | 653 | # adds different betting cites to the first array 654 | books = driver.find_elements_by_xpath('//div[@class="op-block__books"]/div/a') 655 | betting_sites = [] 656 | betting_sites.append("Opening Odds") 657 | 658 | count1 = 0 659 | for book in books: 660 | if(book.get_attribute("aria-label") == book.get_attribute("aria-label").upper()): 661 | if(count1 != 0): 662 | betting_sites.append(book.get_attribute("aria-label")) 663 | else: 664 | count1+=1 665 | 666 | # gets the match participants names 667 | #TODO NEEDS TO BE UPDATED FOR NCAFF NAMES 668 | names = driver.find_elements_by_xpath('//div[@class="op-block__matchup-team-wrapper"]/div/a/span') 669 | # //*[contains(@class,"op-block__matchup-team-wrapper")]/div/a/span //*[contains(@class,"op-block__matchup-team-wrapper")]/div/a/span 670 | name_array = [] 671 | name_array2 = [] 672 | 673 | count = 0 674 | counter = 0 675 | for name in names: 676 | if(count == 0): 677 | if(counter % 2 == 0): 678 | name1 = name.text 679 | name_array.append(name1) 680 | counter+=1 681 | else: 682 | name2 = name.text 683 | name_array2.append(name2) 684 | counter+=1 685 | count+=1 686 | else: 687 | count-=1 688 | 689 | # Getting the odds from each site and removes opening odds 690 | odds_top = driver.find_elements_by_xpath('//*[contains(@class,"op-block__cell-first-row")]/div') 691 | odds_top_list = [[]] 692 | counter = 1 #TODO double check to see if this works (not debugged) 693 | c = 0 694 | for top in odds_top: 695 | if(count == 0): 696 | tops = top.text 697 | odds_top_list[c].append(tops) 698 | count+=1 699 | counter+=1 700 | if(counter == len(betting_sites)): 701 | counter=0 702 | odds_top_list[c].pop(0) 703 | odds_top_list.append([]) 704 | c+=1 705 | else: 706 | count-=1 707 | odds_top_list.pop() 708 | 709 | odds_bottom = driver.find_elements_by_xpath('//*[contains(@class,"op-block__cell-second-row")]/div') 710 | odds_bottom_list = [[]] 711 | counter = 1 #TODO double check to see if this works (not debugged) 712 | c = 0 713 | for bot in odds_bottom: 714 | if(count == 0): 715 | bots = bot.text 716 | odds_bottom_list[c].append(bots) 717 | count+=1 718 | counter+=1 719 | if(counter == len(betting_sites)): 720 | counter=0 721 | odds_bottom_list[c].pop(0) 722 | odds_bottom_list.append([]) 723 | c+=1 724 | else: 725 | count-=1 726 | odds_bottom_list.pop() 727 | 728 | # Finding all the null locations (there are participants with 0 odds listed) 729 | nullls = driver.find_elements_by_xpath('//div[@class="op-block__separator odds-block__separator--right"]/following-sibling::div') 730 | null_indecies = [] 731 | counter = 0 732 | for nul in nullls: 733 | if(nul.get_attribute("class") == "op-block__row not-futures no-odds-wrapper"): 734 | null_indecies.append(math.floor(counter/2)) 735 | if(counter == len(odds_bottom_list)*2): 736 | break 737 | counter+=1 738 | 739 | # Quits the website 740 | driver.quit() 741 | 742 | count = 0 743 | for n in null_indecies: 744 | if(n < len(name_array) and n < len(name_array2)): 745 | name_array.pop(n-count) 746 | name_array2.pop(n-count) 747 | count+=1 748 | 749 | # Adding First participant to Odds 750 | i=0 751 | for array in odds_top_list: 752 | array.insert(0, name_array[i]) 753 | i+=1 754 | # Adding Second participant to Odds 755 | i=0 756 | for array in odds_bottom_list: 757 | array.insert(0, name_array2[i]) 758 | i+=1 759 | 760 | # Combining both participant and odds 761 | main_grid = [[]] 762 | i=0 763 | a=0 764 | b=0 765 | for l in range(len(odds_bottom_list)+len(odds_top_list)): 766 | if(i % 2 == 0): 767 | main_grid.append(odds_top_list[a]) 768 | a+=1 769 | else: 770 | main_grid.append(odds_bottom_list[b]) 771 | b+=1 772 | i+=1 773 | 774 | # MIGHT BE ERROR HERE IN THE FUTURE 775 | main_grid.pop(0) 776 | 777 | betting_sites.insert(0, "Participant Names") 778 | betting_sites.pop(1) 779 | main_grid.insert(0, betting_sites) 780 | # All values are now stored in a 2d array called main grid which will be assigned to the grid variable 781 | self.grid = main_grid 782 | 783 | 784 | 785 | 786 | #------------------------------------------------------------------------------------------ 787 | #TODO EVERYTHING PAST THIS POINT IS EXPIRIMENTAL AND DOESN'T WORK AS INTENDED 788 | def draftKingsMMA(self): 789 | self.options.headless = True 790 | chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 791 | # and if it doesn't exist, download it automatically, 792 | # then add chromedriver to path 793 | driver = webdriver.Chrome(options=self.options) 794 | 795 | website = "https://sportsbook.draftkings.com/leagues/mma/88670562" 796 | driver.get(website) 797 | 798 | # Name of team/player 799 | names = driver.find_elements_by_xpath('//div[@class="sportsbook-outcome-body-wrapper"]/div/span') 800 | nameArr = [] 801 | for name in names: 802 | nameArr.append(name.text) 803 | 804 | # Odds of team/player 805 | odds = driver.find_elements_by_xpath('//div[@class="sportsbook-outcome-body-wrapper"]/div/div/span') 806 | oddsArr = [] 807 | for odd in odds: 808 | oddsArr.append(odd.text) 809 | 810 | # Checks if the name is in the grid and if it's not, add it along with odds. 811 | for i in range(len(nameArr)): 812 | # Checks if the name is in the not in the grid and adds the odds. 813 | if(not any(nameArr[i] in sublist for sublist in self.grid)): 814 | self.grid.append([]) 815 | self.grid[len(self.grid)-1].append(nameArr[i]) 816 | self.grid[len(self.grid)-1].append(oddsArr[i]) 817 | else: 818 | # Adds the odds to the given player array if the player exsists on that array 819 | for j in range(len(self.grid)): 820 | if(self.index_of(nameArr[i], self.grid[j][0]) != -1): 821 | self.grid[j].append(oddsArr[i]) 822 | # adds '' to names which are not touched by this method 823 | for i in range(len(self.grid)): 824 | if(len(self.grid[i]) < 2): 825 | self.grid[i].append(''); 826 | # print(self.grid) 827 | driver.close() 828 | 829 | #TODO extra added on players my be a spelling error and in that case something must be done 830 | def CaesarsMMA(self): 831 | self.options.headless = True 832 | chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 833 | # and if it doesn't exist, download it automatically, 834 | # then add chromedriver to path 835 | driver = webdriver.Chrome(options=self.options) 836 | # driver = webdriver.Chrome() 837 | 838 | website = "https://www.williamhill.com/us/co/bet/ufcmma" 839 | driver.get(website) 840 | 841 | #TODO This loads the whole site to scrap all the odds needed (might need to be increased) 842 | driver.execute_script("window.scrollTo(0, 1200);") 843 | time.sleep(0.15) 844 | # time.sleep(0.5) 845 | driver.execute_script("window.scrollTo(0, 2400);") 846 | time.sleep(0.15) 847 | 848 | # Name of team/player 849 | names = driver.find_elements_by_xpath('//div[@class="teamLabel maxIOSHeight"]/span') 850 | nameArr = [] 851 | 852 | for name in names: 853 | print(name.text) 854 | nameArr.append(name.text) 855 | # time.sleep(0.1) 856 | # print(nameArr) 857 | 858 | #TODO not gathering all odds 859 | # Odds of team/player 860 | odds = driver.find_elements_by_xpath('//div[@class="oddsView"]/div') 861 | oddsArr = [] 862 | count = 0 863 | for odd in odds: 864 | # print(odd.text) 865 | #TODO 3 is a number which might need to change for this variable 866 | if (count > 3): 867 | # print(odd.text) 868 | oddsArr.append(odd.text) 869 | count+=1 870 | 871 | # print(oddsArr) 872 | 873 | # print(self.grid) 874 | # Checks if the name is in the grid and if it's not, add it along with odds. 875 | for i in range(len(nameArr)): 876 | # Checks if the name is in the not in the grid and adds the odds. 877 | if(not any(nameArr[i] in sublist for sublist in self.grid)): 878 | #TODO this could be wrong 879 | self.grid.append([]) 880 | self.grid[len(self.grid)-1].append(nameArr[i]) 881 | # Adds a none because Draft kings doesn't have a list if this is checked 882 | self.grid[len(self.grid)-1].append('') 883 | self.grid[len(self.grid)-1].append(oddsArr[i]) 884 | # ADDS ODDS DEPENDING ON THE DRAFTKINGS ARRAY 885 | else: 886 | # Adds the odds to the given player array if the player exsists on that array 887 | for j in range(len(self.grid)): 888 | # print(self.grid[j][0]) 889 | indexNum = self.index_of(nameArr[i], self.grid[j][0]) 890 | if(indexNum != -1): 891 | # print(self.grid[j]) 892 | self.grid[j].append(oddsArr[i]) 893 | # print("conversion") 894 | # print(oddsArr[i]) 895 | # print(".") 896 | # print(self.grid[j]) 897 | # self.grid[j].append(oddsArr[indexNum]) 898 | # adds '' to names which are not touched by this method 899 | for i in range(len(self.grid)): 900 | # if(len(self.grid[i]) < len(self.grid[0])): 901 | if(len(self.grid[i]) < 3): 902 | self.grid[i].append(''); 903 | 904 | # for i in range(len(nameArr)): 905 | # # Checks if the name is in the not in the grid and adds the odds. 906 | # if(any(nameArr[i] in sublist for sublist in self.grid)): 907 | # #TODO this could be wrong 908 | # self.grid.append([]) 909 | # self.grid[len(self.grid)-1].append(nameArr[i]) 910 | # # Adds a none because Draft kings doesn't have a list if this is checked 911 | # self.grid[len(self.grid)-1].append('') 912 | # self.grid[len(self.grid)-1].append(oddsArr[i]) 913 | # # ADDS ODDS DEPENDING ON THE DRAFTKINGS ARRAY 914 | # for i in range(len(self.grid)): 915 | # # if(len(self.grid[i]) < len(self.grid[0])): 916 | # if(len(self.grid[i]) < 3): 917 | # self.grid[i].append(''); 918 | 919 | # print(self.grid) 920 | driver.close() 921 | 922 | def FanduelMMA(self): 923 | chromedriver_autoinstaller.install() # Check if the current version of chromedriver exists 924 | # and if it doesn't exist, download it automatically, 925 | # then add chromedriver to path 926 | driver = webdriver.Chrome() 927 | 928 | website = "https://nj.pointsbet.com/sports/mma/UFC" 929 | self.driver.get(website) 930 | 931 | # Name of team/player 932 | # names = driver.find_elements_by_xpath('//span[@class="ae aj iu iv iw ix ij ik il io iy s gd dw iz h i j ak l m al o am q an br"]') 933 | names = self.driver.find_elements_by_xpath('//span[@class="f1fdaby6"]') 934 | nameArr = [] 935 | print("sad") 936 | for name in names: 937 | print(name.text) 938 | nameArr.append(name.text) 939 | 940 | # Odds of team/player 941 | odds = self.driver.find_elements_by_xpath('//span[@class="fheif50"]') 942 | oddsArr = [] 943 | for odd in odds: 944 | print(odd.text) 945 | oddsArr.append(odd.text) 946 | 947 | # Checks if the name is in the grid and if it's not, add it along with odds. 948 | for i in range(len(nameArr)): 949 | # Checks if the name is in the not in the grid and adds the odds. 950 | if(not any(nameArr[i] in sublist for sublist in self.grid)): 951 | self.grid.append([]) 952 | self.grid[len(self.grid)-1].append(nameArr[i]) 953 | self.grid[len(self.grid)-1].append(oddsArr[i]) 954 | else: 955 | # Adds the odds to the given player array if the player exsists on that array 956 | for j in range(len(self.grid)): 957 | if(self.index_of(nameArr[i], self.grid[j]) != -1): 958 | self.grid[j].append(oddsArr[i]) 959 | # adds '' to names which are not touched by this method 960 | for i in range(len(self.grid)): 961 | # The integer number should change with the position which the code is being declaired 962 | if(len(self.grid[i]) < 4): 963 | self.grid[i].append(''); 964 | # self.grid[i].append(''); 965 | # print(self.grid) 966 | self.driver.close() --------------------------------------------------------------------------------