You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BeautifulSoup报错'NavigableString'无find_all属性,网页爬取求助

解决BeautifulSoup中NavigableString无find_all属性的报错

问题根源

你遇到的AttributeError: 'NavigableString' object has no attribute 'find_all',是因为在遍历home_substititions.find('tbody')的子节点时,除了目标<tr>标签,还会混入空白文本节点(比如换行、空格)。这些文本节点在BeautifulSoup里属于NavigableString类型,根本没有find_all方法,自然会报错。

原来的循环for table in home_substititions.find('tbody'):会把tbody下的所有子节点都拿出来遍历,包括那些看不见的空白文本,当循环到这些文本节点时,调用table.find_all('tr')就触发了错误。

快速修复方案

最省心的办法是直接定位到tbody下的所有<tr>标签,跳过那些无关的文本节点。这样循环变量只会是合法的Tag对象,不会再出现类型错误。同时我也帮你修正了代码里的几个小问题:

import requests
from bs4 import BeautifulSoup
import uuid
from datetime import timedelta

link = 'https://rugby.statbunker.com/competitions/MatchDetails/World-Cup-2019/Japan-VS-Russia?comp_id=606&match_id=39737&date=20-Sep-2019'
response = requests.get(link)
html_loop = response.content
soup_loop = BeautifulSoup(html_loop, 'html.parser')
home_substititions = soup_loop.find('table', {'id': 'homeSubs'})
homeSubstitutionEvents = []
# 这里替换成你实际的game对象
game = {'gameTime': ...}  

# 直接获取tbody下的所有tr标签,避免遍历文本节点
for row in home_substititions.find('tbody').find_all('tr'):
    substitutionEvent = {}
    substitutionEvent['uuid'] = uuid.uuid1()
    # 一次性获取所有td,减少重复调用
    tds = row.find_all('td')
    # 先检查td数量,防止索引越界报错
    if len(tds) >= 5:
        substitutionEvent['playerIn'] = tds[2].text.strip()
        substitutionEvent['playerOut'] = tds[4].text.strip()
        time_text = tds[0].text.strip()
        time_part = time_text.split('`')[0]
        # 确保时间部分是数字再转换
        if time_part.isdigit():
            # 修正timedelta的写法,不需要.Timedelta
            substitutionEvent['subTime'] = game['gameTime'] + timedelta(minutes=int(time_part))
        else:
            substitutionEvent['subTime'] = ''
        homeSubstitutionEvents.append(substitutionEvent)

另一种思路:过滤非标签节点

如果你一定要保留遍历tbody子节点的逻辑,可以在循环里先判断当前节点是不是Tag类型,跳过文本节点:

from bs4.element import Tag

# ... 前面的代码不变 ...
for node in home_substititions.find('tbody'):
    # 只处理Tag对象,跳过文本节点
    if not isinstance(node, Tag):
        continue
    # 接下来再处理node(也就是原来的table变量)
    if node.find_all('tr'):
        # ... 你的原有逻辑 ...

这样也能避免触发AttributeError。

内容的提问来源于stack exchange,提问作者greenmeansgo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 18:57:52