使用BeautifulSoup4与Selenium爬虫时,缺失元素未返回None的问题解决
现有代码的核心问题定位
你当前代码的逻辑bug出在循环匹配DOM元素的分支逻辑错位:
- 你把
append(None)的逻辑嵌套在了soup.findAll("th", text=re.compile("Living area"))的遍历循环内部,当页面不存在匹配的th标签时,findAll返回空列表,内部的所有分支(包括else: area.append(None))根本不会被执行 - 就算找到匹配元素,如果意外匹配到了多个符合规则的th标签,还会出现单个页面往列表追加多个值的情况,进一步打乱列表长度和遍历页面数的对应关系
- 之前写的宽泛裸
except捕获也会因为逻辑错位,无法触发预期的占位补全效果
修正后的实现逻辑
核心调整思路:每一次循环跳转完成后,先把当前页面的默认返回值设为None,只有成功提取到目标字段时,再把默认值替换为实际提取的文本,最后统一追加到结果列表,保证15次循环对应15个列表元素。
修正后的关键代码段:
area = list() for i in range(15): # 为当前循环的目标字段预设None占位 current_area = None # 点击跳转下一个房源详情页 python_button = driver.find_elements_by_xpath('//*[@id="classifiedNavigation"]/ul/li[2]/a')[0] python_button.click() time.sleep(random.uniform(1.0, 3.0)) soup = BeautifulSoup(driver.page_source, "html.parser") # 只匹配第一个符合规则的th标签,避免多值重复追加 matched_th = soup.find("th", string=re.compile("Living area")) if matched_th: target_td = matched_th.find_next_sibling("td") if target_td and target_td.text.strip(): current_area = target_td.text.strip() # 无论是否匹配到内容,都把当前循环的结果追加进列表 area.append(current_area) houses = {"Area": area} print(houses)
额外优化注意点
- 把原来的
soup.findAll替换为soup.find,单页详情页的"Living area"字段只会出现一次,不需要遍历全部匹配项 - 移除无作用的裸
except捕获,明确判断每一步的元素存在性,避免误吞其他运行异常 - 初始化BeautifulSoup时显式传入解析器(比如
html.parser),避免不同环境下解析行为不一致 - 后续扩展其他房源字段时,全部沿用“当前循环先设None、匹配到再覆盖、最后统一append”的逻辑,就能保证所有字段列表的长度和实际遍历的房源数完全对齐,直接可以转换为规范的DataFrame
注意:每轮循环的
append动作必须放在循环块的最外层,不受DOM匹配结果的分支判断影响,就不会出现列表长度和遍历页面数不匹配的问题。
内容的提问来源于stack exchange,提问作者Sergiy Polovynko
相关产品推荐
相关产品推荐

