BeautifulSoup配合Selenium爬取whoscored数据不稳定偶发空结果如何解决
whoscored赛事数据爬取不稳定问题解决方案
核心原因
你遇到的不稳定、空返回问题本质是页面异步渲染未完成就提前解析源码:whoscored的球员、评分数据都是JS动态加载的,调用driver.get()后页面不会立刻渲染完所有目标元素,你直接拿当前源码自然经常找不到对应节点。同时你的原代码还有2个明显问题:
- 目标链接末尾多了一个多余的
.,可能导致页面跳转异常 - 未导入pandas库就直接用
pd调用方法
修复方案
1. 加入显式等待逻辑
用selenium自带的WebDriverWait等待目标元素加载完成后再解析源码,比固定time.sleep效率更高、兼容性更好。
2. 多场爬取适配逻辑
每次切换赛事链接后,都重新执行等待逻辑,不要复用之前的soup对象,爬完每场后主动清除cookie避免反爬拦截。
3. 反爬优化
添加请求头伪装浏览器,多场爬取时每次请求加3-5秒的间隔,避免被网站识别为爬虫封IP。
修正后的可运行代码
import pandas as pd import time from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 修正多余的末尾. match_link='https://www.whoscored.com/Matches/1549539/Live/England-Premier-League-2021-2022-Brentford-Arsenal' # 可选:添加无头模式后台运行 opt = webdriver.ChromeOptions() opt.add_argument('user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36') # opt.add_argument('--headless=new') # 不需要弹窗可以打开这行 driver=webdriver.Chrome('C:\\Program Files (x86)\\chromedriver.exe', options=opt) driver.get(match_link) # 显式等待最多10秒,直到球员链接元素出现 try: WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, 'a.player-link span.iconize.iconize-icon-left')) ) except: print("等待元素加载超时,检查网络或页面是否正常") driver.quit() exit() # 确认元素加载完成后再拿源码解析 soup=BeautifulSoup(driver.page_source,'html.parser') Players_list=[] Player_rating=[] try: player_name=soup.select('a.player-link span.iconize.iconize-icon-left') player_rating=soup.select('td.rating') for nme in player_name: Players_list.append(nme.text.strip()) for rat in player_rating: Player_rating.append(rat.text.strip()) except: print('NO ELEMENT') # 合并数据导出 df=pd.DataFrame({'球员姓名': Players_list, '评分': Player_rating}) df.to_csv('brentford-arsenal.csv', index=False, encoding='utf-8-sig') # 用完记得关闭driver driver.quit()
多场爬取注意事项
- 每次跳转新的赛事链接后,都要重新执行上述的显式等待逻辑,再解析页面
- 每爬完一场建议调用
driver.delete_all_cookies()清除缓存,间隔3秒以上再请求下一场 - 如果频繁出现超时,可以适当拉长显式等待的最长时间,或者加代理IP分散请求
内容的提问来源于stack exchange,提问作者aliff nabil
相关产品推荐
相关产品推荐

