如何使用BeautifulSoup获取div内所有p标签文本并解决爬取报错
报错原因
三个核心逻辑问题触发运行错误:
- 循环直接遍历目标div的所有直接子节点,这些节点包含
<h2>、<figure>等非段落标签,对这类节点执行find('p')会返回空值None,后续访问.text属性就会抛出'NoneType' object has no attribute 'text'错误。 - 写死的div类名中
css-1vkfgk0是前端构建时生成的动态类名,页面迭代后会随机变更,极易导致soup.find()定位不到目标div返回None,后续逻辑也会触发空值错误。 - 原逻辑即使不报错,也只会提取每个子节点下的第一个p标签,会遗漏同层级的其他正文段落,提取结果不完整。
修复后代码
不需要遍历div的所有子节点,直接在定位到的正文容器下调用find_all('p')拉取全部段落标签即可,同时优化类名匹配逻辑避免动态类名失效问题:
import requests from bs4 import BeautifulSoup article = requests.get(url) soup = BeautifulSoup(article.content, 'html.parser') # 提取标题、作者,加strip去除首尾多余空白 article_title = soup.find('h1').text.strip() article_author = soup.find('a', class_='author-link').text.strip() article_text = "" # 定位正文div:匹配固定类名片段,忽略动态生成的css-开头类名 article_container = soup.find('div', class_=lambda class_val: class_val and 'wysiwyg--all-content' in class_val) if article_container: # 直接获取容器下所有p标签 all_paragraphs = article_container.find_all('p') # 拼接段落,过滤空内容 article_text = "\n".join([p.text.strip() for p in all_paragraphs if p.text.strip()]) # 后续按需处理提取到的正文即可 print(article_title) print(article_author) print(article_text)
可选优化
如果页面中正文区域夹杂了相关推荐、广告、版权声明等无关内容,可以在拼接段落的列表推导式中增加过滤规则,比如:
- 过滤带特定class的p标签(如推荐内容的专属类名)
- 过滤包含固定广告文案的段落
- 如果需要保留小标题,可以额外提取容器下的
<h2>标签按顺序插入到正文对应位置
内容的提问来源于stack exchange,提问作者i'mgnome
相关产品推荐
相关产品推荐

