使用Beautiful Soup获取div子节点抓取守望先锋联赛数据无返回如何解决
守望先锋联赛赛程爬虫失效问题排查与解决
问题原因
- 静态请求无法获取动态渲染内容:守望先锋联赛官网的赛程数据是通过JavaScript客户端渲染生成的,直接通过
requests等工具请求原始HTML返回的内容中,不包含你要提取的赛程DOM节点,因此bs4无法匹配到对应元素,matches返回空列表。 - 动态类名匹配失效:你使用的类名如
schedule-boardstyles__ContainerCards-j4x5cc-8 jcvNlt属于CSS-in-JS方案编译生成的类名,后面的随机哈希后缀(如j4x5cc-8、jcvNlt)会随站点版本更新变化,硬编码全量匹配非常不稳定,很容易出现匹配不到的情况。
解决方案
- 首先解决动态内容获取问题:
- 方案一:使用Selenium、Playwright等无头浏览器工具加载页面,等待JS渲染完成后再提取页面源码交给bs4解析,即可拿到完整的赛程节点。
- 方案二(更推荐):打开浏览器开发者工具的「网络」面板,筛选Fetch/XHR请求,找到直接返回赛程JSON数据的后端接口,直接请求接口获取结构化数据,无需解析HTML,效率和稳定性更高。
- 其次优化节点匹配规则:
不要匹配完整带哈希的类名,改用匹配类名固定前缀的方式,示例匹配规则如下:match_schedule = [] # 匹配外层容器,*= 表示class包含指定前缀即可 matches = bs.select('div[class*="schedule-boardstyles__ContainerCards"]') for match in matches: # 匹配单场比赛卡片 rows = match.select('div[class*="match-cardstyles__Container"]') for row in rows: # 同理匹配战队名、比分的class前缀 team_list = row.select('p[class*="match-cardstyles__MiddleText"]') score_list = row.select('p[class*="match-cardstyles__ScoreText"]') if len(team_list)>=2 and len(score_list)>=2: team1, team2 = team_list[0].text, team_list[1].text score1, score2 = score_list[0].text, score_list[1].text temp = f'team_1:{team1}, score:{score1}-{score2}, team_2:{team2}' print(temp) match_schedule.append(temp)
内容的提问来源于stack exchange,提问作者eucalysis
相关产品推荐
相关产品推荐

