如何修复NHL赛事收盘赔率Python爬取程序?
NHL赛事赔率爬取错误修复与写入效率优化
一、错误原因与修复
你的问题确实出在div嵌套的循环逻辑上:原代码遍历所有GameDetailsCard__row--3rKYp类型的div,每次循环都会覆盖odds变量,最后得到的是页面中最后一个该类型div的内容。而部分赛事页面里,裁判信息的div排在赔率div之后,就导致错误地抓取了裁判姓名。
修复思路:直接定位到包含“Closing Odds”(收盘赔率)的行,再提取对应的赔率内容,无需遍历所有行。
修改后的单场数据爬取函数:
def get_match_data(url_val, file): response = requests.get(url_val) soup = BeautifulSoup(response.content, "html.parser") matchtitle = soup.find('h1', {'class': "sr-only"}) if not matchtitle: return # 跳过无标题的无效页面 # 精准定位"收盘赔率"所在行 odds_row = soup.find("div", string="Closing Odds") if odds_row: # 获取该行对应的赔率内容 odds = odds_row.find_next("div", {"class": "GameDetailsCard__content--2L_KF"}) if odds: file.write(matchtitle.text + " " + odds.text + "\n")
二、文件写入效率优化
原代码每次写入都重复打开、关闭文件,频繁IO操作会拖慢运行速度。优化方案是仅打开一次文件,在批量爬取全程保持文件打开状态,完成所有写入后自动关闭。
修改后的完整代码:
import requests from bs4 import BeautifulSoup # 爬取单场赛事数据 def get_match_data(url_val, file): response = requests.get(url_val) soup = BeautifulSoup(response.content, "html.parser") matchtitle = soup.find('h1', {'class': "sr-only"}) if not matchtitle: return # 精准定位收盘赔率行 odds_row = soup.find("div", string="Closing Odds") if odds_row: odds = odds_row.find_next("div", {"class": "GameDetailsCard__content--2L_KF"}) if odds: file.write(matchtitle.text + " " + odds.text + "\n") # 批量处理赛事链接 def multi_games_url_handler(link): # 一次性打开文件,持续写入 with open("NHL_GAMES.txt", "a", encoding="utf-8") as file: for x in range(26500, 26715): url = link + str(x) get_match_data(url, file) # 主程序执行 if __name__ == "__main__": link = "https://www.thescore.com/nhl/events/" multi_games_url_handler(link)
关键优化点说明
- 精准元素定位:通过
soup.find("div", string="Closing Odds")直接锁定赔率行,彻底避免变量覆盖问题。 - 减少IO操作:使用
with语句管理文件,全程保持打开状态,完成所有写入后自动关闭,大幅提升效率。 - 异常防护:加入空值判断,避免无效页面导致程序崩溃。
内容的提问来源于stack exchange,提问作者JamieQUECE
相关产品推荐
相关产品推荐

