使用BeautifulSoup爬取NBA Reference 2021赛季杂项统计表返回None求助
问题核心原因排查
跑不通的原因非常明确,没有玄学问题:
- 请求层面:原代码用
http协议发请求、没配置合法的浏览器请求头,很容易被网站反爬拦截,返回的根本不是完整的2021NBA赛季页面源码 - 页面结构层面:这个站点对非首屏的长表格(包括杂项统计块)做了延迟加载,初始返回的HTML里,目标表格不是直接裸露在DOM节点中的,而是被包裹在HTML注释标签里,BeautifulSoup默认的
find方法不会主动解析注释内部的内容,自然定位不到 - 解析层面:初始化BeautifulSoup的时候没指定明确的解析器,不同运行环境下的解析容错逻辑有差异,也可能导致节点识别失效
可直接运行的修复方案
按照上述问题点逐一修正,完整可运行的代码如下:
from bs4 import BeautifulSoup, Comment from urllib.request import urlopen, Request import pandas as pd # 配置带合法请求头的HTTPS请求,规避反爬拦截 target_url = "https://www.basketball-reference.com/leagues/NBA_2021.html" request = Request(target_url, headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36" }) page_content = urlopen(request).read() soup = BeautifulSoup(page_content, "html.parser") # 遍历所有注释节点,定位被包裹的目标表格 all_comments = soup.find_all(string=lambda node: isinstance(node, Comment)) target_table = None for single_comment in all_comments: comment_soup = BeautifulSoup(single_comment, "html.parser") target_table = comment_soup.find("table", id="misc_stats") if target_table: break # 验证表格是否读取成功 if target_table: print("成功定位杂项统计表格") # 用pandas转换为结构化数据 misc_df = pd.read_html(str(target_table))[0] print(misc_df.head())
新手操作注意事项
- 后续如果再遇到
soup.find返回None的情况,可以先把拿到的页面源码打印出来,搜索目标表格的id字符串,确认源码里是否真的包含目标内容,避免在被反爬返回的拦截页里反复找节点 - 从注释中提取出表格HTML后,再传入
pd.read_html方法即可正常转换为DataFrame,不需要额外调整表格结构 - 不要随意提高请求频率,该站点对高频爬虫请求会做IP临时封禁处理,建议每次请求间隔3-5秒
内容的提问来源于stack exchange,提问作者abso-shen123
相关产品推荐
相关产品推荐

