You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Selenium Geckodriver爬取香港赛马会网站出现ReferenceError错误求助

问题:爬取香港赛马会赔率的代码突然失效,提示winOddsByRace未定义

我用于爬取香港赛马会网站赔率数据的代码,此前数月运行稳定从未崩溃:

wb = xw.Book("jockeyclub.xlsx")
rc1 = wb.sheets['Race Card 1']

def scrape_odds(url, worksheet):
    # 指定geckodriver路径
    gecko_driver_path = '/Users/nicholaschan/Desktop/hkjcwebscraping/geckodriver'

    # 创建GeckoDriver服务实例
    gecko_service = Service(executable_path=gecko_driver_path)

    # 初始化Firefox浏览器
    driver = webdriver.Firefox(service=gecko_service)

    # 访问目标页面
    driver.get(url)

    # 等待页面加载
    driver.implicitly_wait(10)

    # 通过JS变量获取赔率数据
    win_odds_string = driver.execute_script('return winOddsByRace')

    # 打印并写入Excel
    print(win_odds_string)
    worksheet.range('A26').value = win_odds_string

    # 关闭浏览器
    driver.quit()


scrape_odds('https://bet.hkjc.com/racing/pages/odds_wp.aspx?lang=en&date=2024-01-14&venue=ST&raceno=1',rc1)

但今日运行时,虽然能正常打开Firefox并访问目标链接,却立即抛出以下错误:

File "/Users/nicholaschan/Desktop/hkjcwebscraping/scrapodds1.py", line 52, in <module>
    scrape_odds('https://bet.hkjc.com/racing/pages/odds_wp.aspx?lang=en&date=2024-01-14&venue=ST&raceno=1',rc1)
  File "/Users/nicholaschan/Desktop/hkjcwebscraping/scrapodds1.py", line 42, in scrape_odds
    win_odds_string = driver.execute_script('return winOddsByRace')
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/selenium/webdriver/remote/webdriver.py", line 407, in execute_script
    return self.execute(command, {"script": script, "args": converted_args})["value"]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/selenium/webdriver/remote/webdriver.py", line 347, in execute
    self.error_handler.check_response(response)
  File "/Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/site-packages/selenium/webdriver/remote/errorhandler.py", line 229, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.JavascriptException: Message: ReferenceError: winOddsByRace is not defined
Stacktrace:
@https://bet.hkjc.com/racing/pages/odds_wp.aspx?lang=en&date=2024-01-14&venue=ST&raceno=1:2:7
@https://bet.hkjc.com/racing/pages/odds_wp.aspx?lang=en&date=2024-01-14&venue=ST&raceno=1:3:8

我尝试修改代码的部分内容,但每次运行仍会报错。请问为何此前运行正常的代码突然失效?


原因分析与解决思路

核心原因

代码突然失效的大概率是以下几种情况:

  • 网站前端逻辑更新:香港赛马会修改了页面的JavaScript结构,之前全局暴露的winOddsByRace变量被移除、重命名或改为局部变量,导致你的代码无法获取该变量。这是网站迭代或反爬的常见操作。
  • 等待机制不充分:你使用的implicitly_wait(10)是隐式等待,仅能等待DOM元素加载完成,但无法确保所有JavaScript变量都初始化完成。现在页面可能需要更长时间生成该变量,或者需要触发交互才会出现。
  • 反爬策略触发:网站可能检测到爬虫行为,限制了JavaScript变量的暴露,或者需要验证(如Cookie、用户代理)才能获取数据。

解决建议

  1. 验证变量状态:手动打开目标页面,按F12打开开发者工具,在Console标签输入winOddsByRace,确认该变量是否真的不存在。如果不存在,搜索页面内的赔率相关关键词,寻找新的变量名(比如winOdds、raceOddsData等)。
  2. 优化等待逻辑:替换隐式等待为显式等待,等待目标JavaScript变量加载完成:
from selenium.webdriver.support.ui import WebDriverWait

# 替换原有的driver.implicitly_wait(10)
wait = WebDriverWait(driver, 20)
# 等待winOddsByRace变量被定义
wait.until(lambda driver: driver.execute_script('return typeof winOddsByRace !== "undefined"'))
  1. 模拟用户行为:添加真实的用户代理(UA),保存并复用Cookie,或者在页面加载后模拟滚动、点击等操作,避免被反爬机制拦截。
  2. 更换数据获取方式:如果无法再通过JS变量获取数据,可以尝试直接解析页面HTML元素提取赔率;或者通过开发者工具的Network标签,找到加载赔率数据的API接口,直接调用接口获取数据(这种方式更稳定且效率更高)。

内容的提问来源于stack exchange,提问作者NNBananas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 12:05:06