使用BeautifulSoup抓取体育网站数据仅返回模板变量如何解决
问题原因
你拿到模板占位符的核心原因是该网站采用前端JS动态渲染机制:服务器首次返回的HTML只包含页面框架和模板语法,运动员的真实数据需要浏览器执行页面内嵌的JS脚本,异步请求后端接口后才会填充到页面上。requests库只能获取未执行JS的原始静态HTML,因此无法拿到渲染后的真实内容。
解决方案
分两类实现,你可以根据需求选择:
- 方案1:直接调用后端数据接口(推荐,性能最高)
打开浏览器F12开发者工具,切换到「网络」选项卡,刷新页面后筛选XHR/ Fetch类型的请求,就能找到返回运动员完整信息的后端接口,直接请求该接口即可拿到结构化的JSON数据,无需解析HTML。
示例逻辑代码如下:
import requests def scrape_player_api(player_id): # 替换为你抓到的真实接口地址,player_id可以从原页面URL中提取 api_url = f"https://api.eurohandball.com/player/{player_id}" # 补充必要的请求头,避免被接口拦截 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" } resp = requests.get(api_url, headers=headers) player_data = resp.json() # 直接从JSON中提取需要的字段 print(f"姓名:{player_data['person']['lastName']} {player_data['person']['firstName']}") print(f"年龄:{player_data['age']}") print(f"身高:{player_data['height']}")
- 方案2:使用支持JS渲染的爬虫工具
如果不想花时间找接口,可以用Selenium、Playwright这类模拟浏览器的工具,自动加载页面并执行JS,等页面渲染完成后再提取元素内容,和你原来用BeautifulSoup的逻辑基本一致。
以Playwright为例的示例代码:
from playwright.sync_api import sync_playwright from bs4 import BeautifulSoup def scrape_player_render(player_url): with sync_playwright() as p: # 启动无头浏览器 browser = p.chromium.launch(headless=True) page = browser.new_page(user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36") page.goto(player_url) # 等待目标元素加载完成 page.wait_for_selector(".player-info-row", timeout=5000) # 获取渲染后的页面HTML html = page.content() browser.close() # 后续解析逻辑和你原来的代码完全一致 player_soup = BeautifulSoup(html, 'html.parser') div = player_soup.find('div', {'class' : 'player-info-row'}) player_name = div.text.strip() print(player_name) if __name__ == '__main__': scrape_player_render('https://ehfcl.eurohandball.com/men/2021-22/player/LFpFsiLDFvxs_tXnKlFAQw/luis-frade/')
注意使用Playwright需要先执行
pip install playwright安装依赖,再执行playwright install chromium安装浏览器内核。
内容的提问来源于stack exchange,提问作者Duarte Guerreiro
相关产品推荐
相关产品推荐

