You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用BeautifulSoup爬取数据存入Pandas DataFrame时部分单元格值缺失

解决网页爬取中部分数据缺失的问题

问题分析

你的代码出现数据缺失,核心是两处逻辑没处理页面结构的异常情况:

  1. 电话号码缺失:第一行的电话单元格无有效文本,直接调用replace会导致None值存入列表,最终在DataFrame中显示为空。
  2. 邮政编码缺失:依赖next_element获取邮编的逻辑不稳定,部分行的地址单元格DOM结构不同,next_element不存在或无有效文本,导致提取失败。

修复方案

1. 健壮处理电话号码提取

先判断电话文本是否存在,再做格式处理,不存在时存入空值:

# 替换原Phone.append行
phone_text = cells[5].find(text=True)
Phone.append(phone_text.replace('T: ', '') if phone_text else '')

2. 用正则提取邮政编码(更可靠)

加拿大邮编固定为A1A 1A1格式(字母+数字+字母+空格+数字+字母+数字),直接从地址单元格的所有文本中匹配该格式,摆脱对DOM结构的依赖:

import re

# 替换原PostalCode.append行
address_cell_text = cells[4].get_text(strip=True, separator=' ')
postal_match = re.search(r'[A-Z]\d[A-Z] \d[A-Z]\d', address_cell_text)
PostalCode.append(postal_match.group() if postal_match else '')

完整修改后的代码

from urllib.request import urlopen
from bs4 import BeautifulSoup
import pandas as pd
import re

schools = "https://www.winnipegsd.ca/page/9258/school-directory-a-z"
page = urlopen(schools)

soup = BeautifulSoup(page, features="html.parser")
table_ = soup.find('table')

Name = []
Address = []
PostalCode = []
Phone = []
Grades = []
Website = []

for row in table_.findAll("tr"):
    cells = row.findAll('td')
    if len(cells) == 6:
        # 提取学校名称
        name_text = cells[1].find(text=True)
        Name.append(name_text if name_text else '')
        
        # 提取地址
        address_text = cells[4].find(text=True)
        Address.append(address_text if address_text else '')
        
        # 正则提取邮编
        address_cell_text = cells[4].get_text(strip=True, separator=' ')
        postal_match = re.search(r'[A-Z]\d[A-Z] \d[A-Z]\d', address_cell_text)
        PostalCode.append(postal_match.group() if postal_match else '')
        
        # 提取并处理电话
        phone_text = cells[5].find(text=True)
        Phone.append(phone_text.replace('T: ', '') if phone_text else '')
        
        # 提取年级
        grades_text = cells[2].find(text=True)
        Grades.append(grades_text if grades_text else '')
        
        # 提取网站链接
        link_tag = cells[1].find('a')
        Website.append('https://www.winnipegsd.ca' + link_tag['href'] if link_tag else '')

# 构建DataFrame
df = pd.DataFrame({
    'Name': Name,
    'Street Address': Address,
    'Postal Code': PostalCode,
    'Phone Number': Phone,
    'Grades': Grades,
    'Website': Website
})

df.to_csv("file.tsv", sep="\t", index=False)

额外优化建议

  • 用字典直接构建DataFrame更清晰,避免逐个列赋值可能出现的长度不匹配问题。
  • 对所有字段都做空值判断,避免因页面结构变化导致的报错或数据缺失。

内容的提问来源于stack exchange,提问作者thewire

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 19:10:25