Python爬虫:提取页面人员信息时contents返回空值的问题排查
问题
我需要抓取某Wayback Machine存档的NIH公开名册页面中的人员信息,目标是提取姓名、职业等字段组成人员信息列表(已知部分人员信息行数更多,需特殊处理)。
目前编写的代码片段:
sep = soup.find_all("p")[1:]
后续计划用以下逻辑实现(虽不够优雅但可行):
for bullet in sep: if len(bullet.find_all("br"))==9: person = {} person["NAME"]=bullet.contents[0].strip() person["PROFESSION"]=bullet.contents[2].strip() person["DEPARTMENT"]=bullet.contents[6].strip()+" "+bullet.contents[8].strip() person["INSTITUTION"]=bullet.contents[12].strip() person["LOCATION"]=bullet.contents[14].strip()
(需根据len()结果调整索引并适配多种情况)
但测试时发现bullet.contents[0].strip()仅返回空值(例如测试sep[1].contents[0].strip()得到""),请问该问题的原因是什么?如何修复?
原因分析与修复方案
原因
bullet.contents[0]返回空值的核心原因是:页面的<p>标签内部,第一个子节点是空白文本节点(比如换行、空格、制表符这类不可见的空白字符)。BeautifulSoup解析HTML时,会把这些空白字符当作独立的文本节点存入contents列表,所以你取第一个元素时,本质是拿到了一段空白内容,strip()后自然是空字符串。
修复方案
可以用两种思路解决:
思路1:过滤空白文本节点
遍历contents时跳过空白节点,直接提取有效文本节点:
for bullet in sep: # 提取所有非空白的文本内容,按原逻辑对应字段 non_empty_contents = [node.strip() for node in bullet.contents if node.strip()] if len(bullet.find_all("br")) == 9: person = {} person["NAME"] = non_empty_contents[0] person["PROFESSION"] = non_empty_contents[1] person["DEPARTMENT"] = f"{non_empty_contents[3]} {non_empty_contents[4]}" person["INSTITUTION"] = non_empty_contents[6] person["LOCATION"] = non_empty_contents[7] # 后续处理逻辑...
思路2:用get_text()按分隔符拆分
利用<br>作为分隔符,直接提取<p>内的所有文本并分割,逻辑更简洁:
for bullet in sep: # 按<br>分割文本,同时过滤空白内容 parts = [part.strip() for part in bullet.get_text(separator="|").split("|") if part.strip()] if len(parts) == 8: # 对应原逻辑中9个<br>分割出的8个有效字段 person = {} person["NAME"] = parts[0] person["PROFESSION"] = parts[1] person["DEPARTMENT"] = f"{parts[3]} {parts[4]}" person["INSTITUTION"] = parts[6] person["LOCATION"] = parts[7] # 后续处理逻辑...
补充说明
如果页面中不同人员的信息字段数量有差异,建议先打印non_empty_contents或parts的内容,确认每个字段对应的索引后再调整赋值逻辑,避免硬编码索引导致的错误。
内容的提问来源于stack exchange,提问作者Clara HL
相关产品推荐
相关产品推荐

