【问题标题】:How to use Selenium to navigate through sports site for web scraping Soccer Player Prop data?如何使用 Selenium 浏览体育网站以抓取足球运动员道具数据?
【发布时间】:2020-03-01 12:01:50
【问题描述】:

我是编码新手,正在尝试学习如何使用 Selenium 浏览网站。我的最终目标是解析足球运动员道具数据player props,以便使用 Pandas DataFrame 将输出打印到 excel 中。

为了访问此信息,我认为我必须先完成 4 个步骤(如果我错了,请纠正我):

1) 在玩家道具页面选择“OVER/UNDER”标签

2) 向下滚动到“UCL”(Champions League Soccer)

3) 选择“所有可用(所有游戏)”选项

4) 选择标签“Shots(Player)”

我使用 Xpath 找到了“Over/Under”按钮:

更新代码以更改 iframe 并单击 Over/Under 按钮

 from selenium import webdriver
 from time import sleep


 class App:
     def __init__(self,):

         self.driver = webdriver.Chrome('C:\webdrivers\chromedriver.exe')
         self.main_url = 'https://www.betonline.ag/sportsbook/player-props'
         self.driver.get(self.main_url)
         sleep(3)

         self.driver.switch_to.frame("builder")
         element = self.driver.find_element_by_xpath('/html/body/main/div/div/div/div/div[2]/div/div[3]/div[1]/ul/li[3]/a/b')
         element.click()

         sleep(3)
         self.driver.close()

 if __name__ == '__main__':
     app = App()

我现在可以选择“大/小”标签。接下来我将开始执行步骤 2-4。

我要查找的 Soccer Prop 数据是“Player”、“Over”、“Line”和“Under”。

这是我正在寻找的 excel 输出示例:

  Player               Over         Line          Under

Divock Origi          -108          3.5          -120

我希望创建一个循环,以便解析玩家的所有投注信息。

我可以在代码中看到 Over/Under 按钮,但不确定如何正确解析:

我还可以看到玩家数据:

有人对我如何完成这个项目有任何建议吗?任何帮助将不胜感激。我将继续为此工作,如果取得任何额外进展,我将更新我的代码。非常感谢您的意见!

【问题讨论】:

    标签: python pandas selenium parsing web-scraping


    【解决方案1】:

    您能否发布完整的 html-tree 以查看您的路径是否正确?

    编辑:我自己查的。 试试这个按钮

    element = self.driver.find_element_by_css_selector('main div div div div div div div div ul li+li+li a ')
    

    【讨论】:

    • 为了调试,我建议逐步添加更多选择器。看看哪里出了问题。
    • 好的,你@AnanasXpress。在接下来的几天里,我会花更多的时间来解决这个问题。
    【解决方案2】:

    请仔细检查您的页面上是否存在 iframe,您需要在对 Web 元素执行任何操作之前切换到 iframe。

    更多详情请查看链接: https://chercher.tech/python/iframe-selenium-python

    【讨论】:

    • 我会花一些时间研究这个@Rock。泰先生 =)
    【解决方案3】:

    这是在dataframe中显示数据的代码。

    import pandas as pd
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    from selenium import webdriver
    
    driver=webdriver.Chrome("C:\webdrivers\chromedriver.exe")
    driver.maximize_window()
    driver.get("https://www.betonline.ag/sportsbook/player-props")
    WebDriverWait(driver,20).until(EC.frame_to_be_available_and_switch_to_it((By.ID,"builder")))
    WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//li[@class='one-third one-third-remove']//a[./b[contains(.,'Over / Under')]]"))).click()
    WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"div[ng-if='selected.league']"))).click()
    WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//li[@ng-repeat='league in leagues']/a[.//span[text()='UCL']]"))).click()
    WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"div[ng-if^='selected.game']"))).click()
    time.sleep(2)
    WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//li/a[.//div[text()='All Available']]"))).click()
    #WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//span[contains(.,'Shots (Player)')]"))).click()
    
    
    player=[]
    Over=[]
    line=[]
    Under=[]
    Playersname=WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.XPATH,"//div[@class='div-table__row__cell hard--bottom hard--right ng-scope']//a[@class='ng-binding']")))
    for players in Playersname:
        player.append(players.text)
    
    OverAndUnder=WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,"a>b.milli.caps.ng-binding")))
    count=int(len(OverAndUnder)/2)
    x=0
    for i in range(count):
        Over.append(OverAndUnder[x].text)
        Under.append(OverAndUnder[x+1].text)
        x=x+2
    
    lines=WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,"div[ng-class*='overUnder']>b")))
    for l in lines:
        line.append(l.text)
    
    df = pd.DataFrame({"Player":player,"Over":Over,"Line":line, "Under":Under})
    print(df)
    

    输出

     Line  Over           Player Under
    0   3.5  +114     Divock Origi  -149
    1   1.5  -149      Dusan Tadic  +114
    2     3  -114    Gabriel Jesus  -114
    3   2.5  -167     Hakim Ziyech  +127
    4   2.5  -114     Josip Ilicic  -114
    5   2.5  +114      Mason Mount  -149
    6   1.5  -108   Mbwana Samatta  -120
    7   4.5  -137    Mohamed Salah  +106
    8   2.5  +110       Papu Gomez  -143
    9   1.5  +122     Paul Onuachu  -159
    10  1.5  -149    Quincy Promes  +114
    11  2.5  -114  Raheem Sterling  -114
    12    4  +114  Roberto Firmino  -149
    13  3.5  -149       Sadio Mané  +114
    14  3.5  +117    Sergio Agüero  -152
    15  3.5  -120    Tammy Abraham  -108
    16  2.5  +127          Willian  -167
    

    【讨论】:

    • 对于这个回复非常满意......我尝试了这段代码并收到了一个错误(NameError:名称'时间'未定义)。我添加了模块“导入时间”并收到另一个错误(selenium.common.exceptions.StaleElementReferenceException:消息:状态元素引用:元素未附加到页面文档)。我尝试多次运行代码并且它工作一次。 @Kundruk 有什么建议吗?谢谢你的帮助! =)
    • 我尝试再次运行它并收到不同的消息“selenium.common.exceptions.TimeoutExeption: Message:”。在完美运行后立即重新运行脚本。
    • 看起来错误发生在不同的时间。我已经看到它发生在 Over/Under 步骤上。在节目选择UCL之后也发生了这种情况。在程序选择 ALL Available 之后也发生了这种情况。如果有帮助,我可以发送每个错误。
    • 做一件事可能脚本运行​​得更快,所以在每次点击事件之前使用 time.sleep(2)。
    • 这似乎工作得更顺利。但是,我在使用变量“Playersname”的行上遇到了错误(selenium.common.exceptions.TimeoutException: Message:)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-17
    • 1970-01-01
    • 2014-05-23
    相关资源
    最近更新 更多