爬Stack Overflow时遇Python 'NoneType' object has no attribute 'attrs'错误
爬取Stack Overflow docusignapi标签问题数据的None值处理方案
问题场景
爬取https://stackoverflow.com/questions/tagged/docusignapi页面,获取问题的投票数、回答数和浏览量数据时,部分问题返回None值,运行代码触发AttributeError,无法正常打印回答和浏览量信息。
原代码
from bs4 import BeautifulSoup import requests url= "https://stackoverflow.com/questions/tagged/docusignapi" page = requests.get(url) soup = BeautifulSoup(page.text, "html.parser") questions = soup.select(".s-post-summary") questions_data = { "questions": [] } questions = soup.select(".s-post-summary ") for que in questions: q = que.select_one('.s-link').getText() vote_count = que.select_one('.s-post-summary--stats-item-number').text answers = que.select_one('.s-post-summary--stats-item.has-answers').attrs['title'] views = que.select_one('.s-post-summary--stats-item ') print(answers)
报错信息
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-70-b2414da81e70> in <module> 6 q = que.select_one('.s-link').getText() 7 vote_count = que.select_one('.s-post-summary--stats-item-number').text ----> 8 answers = que.select_one('.s-post-summary--stats-item.has-answers').attrs['title'] 9 views = que.select_one('.s-post-summary--stats-item ') 10 print(answers) AttributeError: 'NoneType' object has no attribute 'attrs'
问题原因
- 无回答问题导致选择器失效:
.s-post-summary--stats-item.has-answers仅匹配有回答的问题,无回答的问题会返回None,直接调用attrs必然触发报错。 - 浏览量选择器定位模糊:
.s-post-summary--stats-item匹配所有统计项,无法精准定位浏览量元素,且未处理None情况。
解决代码
from bs4 import BeautifulSoup import requests url= "https://stackoverflow.com/questions/tagged/docusignapi" page = requests.get(url) soup = BeautifulSoup(page.text, "html.parser") questions = soup.select(".s-post-summary") questions_data = { "questions": [] } for que in questions: # 提取问题标题,处理元素不存在的情况 title = que.select_one('.s-link').get_text(strip=True) if que.select_one('.s-link') else "未知标题" # 提取投票数 vote_elem = que.select_one('.s-post-summary--stats-item:nth-child(1) .s-post-summary--stats-item-number') vote_count = vote_elem.get_text(strip=True) if vote_elem else "0" # 提取回答数及详情 answer_elem = que.select_one('.s-post-summary--stats-item:nth-child(2)') if answer_elem: answer_count = answer_elem.select_one('.s-post-summary--stats-item-number').get_text(strip=True) answer_detail = answer_elem.get('title', '无回答') else: answer_count = "0" answer_detail = "无回答" # 提取浏览量(从title属性中提取数字) view_elem = que.select_one('.s-post-summary--stats-item:nth-child(3)') views = view_elem.get('title', '0 次浏览').split()[0] if view_elem else "0" # 存入数据字典 questions_data["questions"].append({ "title": title, "vote_count": vote_count, "answer_count": answer_count, "answer_detail": answer_detail, "views": views }) # 打印当前问题的回答和浏览量 print(f"回答: {answer_detail}, 浏览量: {views}") # 可选:查看所有收集的数据 # print(questions_data)
代码说明
- None值处理:对每个元素提取前做存在性判断,避免直接调用属性报错。
- 精准选择器:使用
:nth-child()指定统计项位置,分别定位投票(第1项)、回答(第2项)、浏览量(第3项)元素。 - 数据格式化:从浏览量元素的
title属性中提取纯数字,统一数据格式。
内容的提问来源于stack exchange,提问作者user11429634
相关产品推荐
相关产品推荐

