Python爬虫在抓取网页数据后,得到的原始内容通常包含大量无用信息,比如多余的空格、HTML标签残留、特殊符号、重复条目等,直接使用这些数据会导致后续分析或存储出现错误,因此掌握数据清洗的相关技巧十分必要。

基础字符串处理技巧
爬虫获取到的文本数据最常见的问题就是存在多余的空白字符,比如换行符、制表符、首尾空格等,使用Python内置的字符串方法就可以快速处理这类问题。
# 原始爬取到的文本数据
raw_text = " 爬取到的标题nt包含多余空白 n"
# 去除首尾空白字符
clean_text = raw_text.strip()
print(clean_text) # 输出:爬取到的标题nt包含多余空白
# 替换中间的换行和制表符为单个空格
clean_text = clean_text.replace("n", " ").replace("t", " ")
print(clean_text) # 输出:爬取到的标题 包含多余空白
# 合并多个连续空格为单个空格
import re
clean_text = re.sub(r"s+", " ", clean_text)
print(clean_text) # 输出:爬取到的标题 包含多余空白
HTML标签残留处理
很多爬虫直接获取的是网页的HTML片段,内容中会夹杂大量<div>、<span>、<a>等标签,需要将这些标签去除只保留文本内容。
import re # 包含HTML标签的原始内容 html_content = "" # 使用正则匹配所有HTML标签并替换为空 text_content = re.sub(r"<[^>]+>", "", html_content) print(text_content) # 输出:这是正文内容附带信息 # 如果需要保留标签内的部分属性内容,可以针对性调整正则规则 # 例如只去除标签,保留标签内的文本和换行 text_content = re.sub(r"<[^/][^>]*>|</[^>]+>", "", html_content) print(text_content) # 输出:这是正文内容附带信息这是正文内容
附带信息
特殊字符与编码处理
爬虫数据中还经常出现HTML实体字符,比如 、<、>,以及编码异常导致的乱码问题,需要针对性处理。
import html
# 包含HTML实体字符的内容
entity_text = "价格: 199元 <原价299元>"
# 转换HTML实体字符为正常字符
normal_text = html.unescape(entity_text)
print(normal_text) # 输出:价格: 199元 <原价299元>
# 处理编码异常问题
# 假设爬取到的数据是 Latin-1 编码的错误字符串
wrong_encode_str = "éèê".encode("latin-1").decode("utf-8", errors="ignore")
# 尝试还原正确编码
try:
correct_str = wrong_encode_str.encode("latin-1").decode("utf-8")
print(correct_str)
except:
# 如果无法还原,使用替换策略处理乱码
correct_str = wrong_encode_str.encode("utf-8", errors="ignore").decode("utf-8")
print(correct_str)
重复数据与格式统一
爬虫过程中可能因为翻页逻辑或者网页结构问题,爬取到重复的数据,同时不同来源的数据格式可能不统一,需要进行去重和格式标准化。
# 模拟爬取到的重复数据列表
raw_data_list = [
{"title": "商品A", "price": "199", "date": "2024-05-01"},
{"title": "商品A", "price": "199", "date": "2024-05-01"},
{"title": "商品B", "price": "299", "date": "2024.5.2"},
{"title": "商品C", "price": "399元", "date": "05/03/2024"}
]
# 去重处理,使用元组作为可哈希的键
unique_data = []
seen = set()
for item in raw_data_list:
key = (item["title"], item["price"], item["date"])
if key not in seen:
seen.add(key)
unique_data.append(item)
# 统一日期格式
from datetime import datetime
for item in unique_data:
date_str = item["date"]
# 尝试多种日期格式解析
for fmt in ("%Y-%m-%d", "%Y.%m.%d", "%m/%d/%Y"):
try:
date_obj = datetime.strptime(date_str, fmt)
item["date"] = date_obj.strftime("%Y-%m-%d")
break
except:
continue
# 统一价格格式,去除非数字字符
item["price"] = re.sub(r"[^d]", "", item["price"])
print(unique_data)
数据校验与异常值处理
清洗后的数据还需要进行校验,比如判断必填字段是否存在、数值是否在合理范围、邮箱或手机号格式是否正确等,过滤掉不符合要求的数据。
import re
# 模拟清洗后的数据
cleaned_data = [
{"name": "张三", "phone": "13800138000", "score": 95},
{"name": "李四", "phone": "12345", "score": 150},
{"name": "", "phone": "13900139000", "score": 88}
]
valid_data = []
for item in cleaned_data:
# 校验姓名不为空
if not item["name"]:
continue
# 校验手机号格式
phone_pattern = r"^1[3-9]d{9}$"
if not re.match(phone_pattern, item["phone"]):
continue
# 校验分数在0-100之间
if not (0 <= item["score"] <= 100):
continue
valid_data.append(item)
print(valid_data)