如何用BeautifulSoup获取带data-v属性的div内容及动态页面爬虫问题
解决Oddsportal动态页面比赛链接爬取问题
问题分析
- 目标页面采用动态渲染,比赛数据由JavaScript异步加载,
requests.get()仅能获取初始静态HTML,无法捕获后续生成的比赛DOM元素 - 你要找的
div标签属于动态生成内容,静态爬取自然返回None,timeout、sleep这类静态爬取的优化方法无法解决根本问题
解决方案:模拟浏览器加载动态内容
由于页面依赖JS渲染,必须用浏览器模拟工具来获取完整的渲染后页面,以下是两种可行方案:
方案1:使用Selenium
Selenium是常用的浏览器自动化工具,能完整模拟用户浏览行为,等待页面加载完成后提取数据。
安装依赖
pip install selenium webdriver-manager
webdriver-manager用于自动管理浏览器驱动,无需手动下载对应版本。
完整代码
from bs4 import BeautifulSoup from selenium import webdriver from selenium.webdriver.chrome.service import Service from webdriver_manager.chrome import ChromeDriverManager from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC # 初始化Chrome浏览器 driver = webdriver.Chrome(service=Service(ChromeDriverManager().install())) target_url = "https://www.oddsportal.com/soccer/france/ligue-1/" try: driver.get(target_url) # 显式等待目标元素加载完成,最长等待10秒 WebDriverWait(driver, 10).until( EC.presence_of_element_located(("css selector", "div.flex.hover:bg-[#f9e9cc].group.border-l.border-r.border-black-borders")) ) # 获取浏览器渲染后的完整页面源码 page_html = driver.page_source soup = BeautifulSoup(page_html, "lxml") # 提取所有目标div中的比赛链接 match_links = [] for div in soup.select("div.flex.hover:bg-[#f9e9cc].group.border-l.border-r.border-black-borders a"): if "href" in div.attrs: # 拼接完整URL full_link = f"https://www.oddsportal.com{div['href']}" match_links.append(full_link) # 输出结果 print("获取到的比赛链接:") for link in match_links: print(link) finally: # 确保浏览器关闭 driver.quit()
代码说明
- 显式等待:通过
WebDriverWait等待目标元素出现,避免因加载速度慢导致的元素查找失败 - page_source:获取浏览器执行JS后的完整HTML,包含所有动态加载的比赛数据
- CSS选择器:用
select方法匹配多class元素,比find更简洁可靠
方案2:使用Playwright
Playwright对现代前端框架的兼容性更好,API更简洁,支持多浏览器。
安装依赖
pip install playwright playwright install # 自动安装浏览器驱动
完整代码
from playwright.sync_api import sync_playwright from bs4 import BeautifulSoup target_url = "https://www.oddsportal.com/soccer/france/ligue-1/" with sync_playwright() as p: # 启动Chromium浏览器,headless=False可可视化查看,True则后台运行 browser = p.chromium.launch(headless=False) page = browser.new_page() page.goto(target_url) # 等待比赛列表元素加载完成 page.wait_for_selector("div.flex.hover:bg-[#f9e9cc].group.border-l.border-r.border-black-borders") # 获取渲染后的页面内容 page_html = page.content() soup = BeautifulSoup(page_html, "lxml") # 提取比赛链接 match_links = [ f"https://www.oddsportal.com{a['href']}" for a in soup.select("div.flex.hover:bg-[#f9e9cc].group.border-l.border-r.border-black-borders a") if "href" in a.attrs ] print("获取到的比赛链接:") for link in match_links: print(link) browser.close()
注意事项
- 避免高频请求,建议添加随机延迟(如
time.sleep(random.uniform(1,3))),防止被网站封禁IP - 若遇到Cloudflare等反爬验证,可能需要额外处理验证码或使用代理IP
- 后续爬取单场比赛赔率时,同样需要用上述动态爬取方式,因为赔率数据也可能是动态加载的
内容的提问来源于stack exchange,提问作者mothas75
相关产品推荐
相关产品推荐

