Python+Selenium爬取Basketball Reference时,如何用XPath选择表格中除最后一列(奖项列)外的所有列?
Python+Selenium爬取Basketball Reference时,如何用XPath选择表格中除最后一列(奖项列)外的所有列?
首先得指出你之前踩的两个XPath坑:
- 你用的
./tr[position() < last()]是在筛选行(选最后一行之前的所有行),不是列,完全没打到点上; ./tr[not(contains(@data-stat, 'awards'))]是找不带awards属性的行,但awards是表格列(<td>)的属性,不是行(<tr>)的,所以这个XPath根本匹配不到任何元素,自然返回空。
接下来给你两个靠谱的解决方案,都是针对列来筛选的:
方案1:根据列的data-stat属性精准排除(推荐)
Basketball Reference的每一列都有唯一的data-stat属性,奖项列的这个属性值就是awards,所以我们可以直接选择每行中data-stat不等于awards的所有单元格:
修改你get_player_row_stats方法里的代码,把原来整行取文本再拆分的逻辑,改成逐个获取符合条件的单元格文本(这样还能避免整行拆分可能带来的错误):
def get_player_row_stats(self) -> list: try: table = self.browser.find_element(By.ID, 'per_game_stats') # 获取所有可见的统计行(排除汇总表头行和隐藏行) rows = table.find_elements(By.XPATH, './tbody/tr[not(@class="thead") and not(@hidden)]') player_data = [] for row in rows: # 选择当前行中除奖项列外的所有单元格 cells = row.find_elements(By.XPATH, './td[not(@data-stat="awards")]') # 提取每个单元格的文本,过滤掉空值 row_stats = [cell.text.strip() for cell in cells if cell.text.strip()] player_data.extend(row_stats) print(player_data) return player_data except Exception as e: print(f"Error extracting row stats: {e}") return None
方案2:通过位置排除最后一列
如果你确认表格的最后一列永远是奖项列,也可以用位置筛选,选择每行中除最后一个<td>外的所有单元格,对应的XPath是./td[position() < last()],把上面代码里的cells那行改成:
cells = row.find_elements(By.XPATH, './td[position() < last()]')
不过这个方案不如方案1稳定,万一网站调整表格列顺序,就会失效,所以优先用方案1。
额外优化提示
- 你原来的代码用
row.text.split(' ')拆分整行文本,虽然当前Basketball Reference的球队都是缩写(无空格)不会出问题,但逐个取单元格文本的方式更健壮,能应对未来可能的格式变化。 - 代码里加入了
[not(@class="thead") and not(@hidden)]来排除表格里的汇总表头行和隐藏行,这些行通常不是你需要的单赛季数据。
备注:内容来源于stack exchange,提问作者BluffShove
相关产品推荐
相关产品推荐

