BeautifulSoup获取文本并保留链接HTML:修复_all_strings重写报错
解决BeautifulSoup重写_all_strings时的TypeError问题
你遇到的TypeError: argument of type 'object' is not iterable,核心原因是重写_all_strings方法时,没有返回可迭代的生成器对象——比如错误用return代替yield,或者处理标签时返回了单个非迭代值。
要实现提取文本时自动包含链接URL,正确的重写方式是让_all_strings以生成器形式逐个产出内容,下面是可行的代码示例:
from bs4 import BeautifulSoup class MyBeautifulSoup(BeautifulSoup): def _all_strings(self, strip=False, types=(str,)): # 遍历所有子节点 for child in self.descendants: # 处理<a>标签:先输出文本,再输出带括号的URL if child.name == 'a' and child.has_attr('href'): text = child.string if text: yield text.strip() if strip else text yield f" ({child['href']})" # 处理普通文本节点,跳过非文本标签 elif child.string is not None and isinstance(child.string, types): string = child.string if strip: string = string.strip() if not string: continue yield string # 测试代码 html = """ <p>这是一段包含<a href="https://example.com">外部链接</a>的文本,还有<a href="/about">内部链接</a>。</p> """ soup = MyBeautifulSoup(html, 'html.parser') print(soup.get_text())
关键说明:
- 必须用
yield逐个产出内容,保证方法返回的是生成器(可迭代对象),这是解决TypeError的核心。 - 处理
<a>标签时先判断child.string是否存在,避免产出None引发迭代异常。 - 调用
get_text()时,会自动遍历_all_strings生成的内容并拼接,无需额外修改调用逻辑。
常见错误排查:
- 如果之前代码用
return替代yield,会直接返回单个对象而非迭代器,触发类型错误。 - 若未过滤空文本节点,可能产出无效内容,干扰迭代流程。
内容的提问来源于stack exchange,提问作者VV75
相关产品推荐
相关产品推荐

