使用Beautiful Soup+Discord.py爬取数据报错:AttributeError求助
问题分析与解决
错误原因
你遇到的AttributeError: 'list' object has no attribute 'find_all'是典型的变量覆盖问题:
- 你先用
soup.find()获取了页面中的<h3>和<div>元素(BeautifulSoup DOM对象) - 紧接着又把
reading和readingtext重新赋值为空列表[] - 后续循环里调用
reading.find_all()时,reading已经变成了列表类型,而列表没有find_all方法,因此触发报错
修正步骤与代码
核心改动点:
- 不要覆盖通过
soup.find()获取到的DOM元素对象,给存储文本的列表换独立变量名 - 避免在循环内重复添加Embed字段,应先收集完所有内容再一次性添加
- 增加空值判断,防止
soup.find()找不到元素时引发新异常 - 移除无效的
format(ctx)调用(原标题字符串无占位符,该调用无意义)
修正后的代码:
@bot.slash_command(name="dailyreading",description="Shows Daily Reading",guild_ids=[testingServerID]) async def dailyreading(ctx): embed = Embed(title="Daily Reading", description="https://bible.usccb.org/daily-bible-reading") page = requests.get("https://bible.usccb.org/daily-bible-reading") soup = BeautifulSoup(page.content, 'html.parser') # 获取页面元素,保留原对象不覆盖 reading_elem = soup.find("h3", class_="content-body") readingtext_elem = soup.find("div", class_="content-body") # 用新变量存储提取的文本 readings = [] reading_texts = [] # 先判断元素是否存在,再执行查找操作 if reading_elem: for i in reading_elem.find_all("a"): readings.append(i.get_text(strip=True, separator=" ")) # 收集完内容后统一添加字段 if readings: embed.add_field(name="Reading:", value="\n".join(readings), inline=False) if readingtext_elem: for s in readingtext_elem.find_all("a"): reading_texts.append(s.get_text(strip=True, separator=" ")) if reading_texts: embed.add_field(name="Context:", value="\n".join(reading_texts), inline=False) await ctx.send(embed=embed)
额外优化说明
- 使用
\n.join(readings)将列表转为换行字符串,让Embed字段的显示更整洁 - 增加空值判断能避免页面结构变动时机器人崩溃,提升稳定性
内容的提问来源于stack exchange,提问作者Jinxed
相关产品推荐
相关产品推荐

