
影刀RPA Excel数据清洗实战空行、重复、乱码、格式混乱的处理数据采集出来不等于能用。你从网页上扒下来的数据往往是脏的——有空行、有重复、有乱码、格式不统一、数字和文本混在一起。这篇文章不讲Excel操作的基本语法讲的是数据清洗的真实套路。用的工具是影刀自带的动作 Python的openpyxl/pandas。清洗前先看一眼数据长什么样很多人一拿到数据就开始写清洗逻辑结果写到一半发现有些脏数据是自己假设之外的。第一件事打开采集到的Excel肉眼扫一遍。看什么有没有空行在哪些位置有没有明显重复的数据数字格式对不对有没有千分位逗号、百分号、负号位置错误日期格式统一吗“2026-07-01” 和 “2026/7/1” 混在一起有没有乱码特别是中文列有没有明显不合理的数据价格负数、数量为零、日期在未来肉眼扫完大概心里有数了再上代码批量处理。不要跳过这一步——有时候你以为是格式问题实际上是采集时就采错了。清洗1删除空行网页采集最容易出现的脏数据——空行。列表里有20个元素某个元素内容为空采回来就是一行空数据。在影刀中处理店群矩阵自动化突破运营极限用ForEach遍历每一行判断是否全为空【读取Excel】→ 全部数据到 data_list clean_list [] FOR EACH row IN data_list: # 判断这一行是否全空 is_empty True FOR EACH cell IN row: IF cell 不为空: is_empty False BREAK END FOR IF is_empty False: 将 row 加入 clean_list END FOR 【写入Excel】→ clean_list 到新文件在Python中处理更高效importopenpyxl wbopenpyxl.load_workbook(data.xlsx)wswb.active# 收集所有非空行clean_rows[]forrowinws.iter_rows(values_onlyTrue):# 检查整行是否全为None或空字符串ifany(cellisnotNoneandstr(cell).strip()!forcellinrow):clean_rows.append(row)# 写入新sheet或新文件ws_cleanwb.create_sheet(清洗后)forrowinclean_rows:ws_clean.append(row)wb.save(data_cleaned.xlsx)print(f清洗前{ws.max_row}行清洗后{len(clean_rows)}行)清洗2删除重复行判断重复的标准不是每列都相同才算重复。有时候你只关心订单号这一列是否重复# 按订单号去重seenset()unique_rows[]headerTrue# 第一行是表头forrowinws.iter_rows(values_onlyTrue):ifheader:unique_rows.append(row)headerFalsecontinueorder_norow[0]# 假设订单号在第一列iforder_nonotinseen:seen.add(order_no)unique_rows.append(row)print(f去重后{len(unique_rows)}行)如果是多列组合判断重复同一客户同一天算重复seenset()unique_rows[]forrowinws.iter_rows(values_onlyTrue):key(row[1],row[2])# 客户名日期 作为唯一键ifkeynotinseen:seen.add(key)unique_rows.append(row)清洗3处理编码乱码从网页上采集的中文存到Excel打开变成乱码。这个问题在CSV文件里尤其常见。原因Excel打开CSV时默认用ANSI编码而你的CSV是UTF-8编码的。解决方法importpandasaspd# 读取时指定编码dfpd.read_csv(data.csv,encodingutf-8)# 或自动检测编码importchardetwithopen(data.csv,rb)asf:rawf.read()resultchardet.detect(raw)encodingresult[encoding]print(f检测到编码{encoding})dfpd.read_csv(data.csv,encodingencoding)df.to_excel(data.xlsx,indexFalse)# 转成xlsx就不会乱码了根本解决方案采集下来直接存成.xlsx而不是.csv。.xlsx自带编码信息不存在乱码问题。清洗4数字格式标准化从网页上采集的数字格式千奇百怪原始值问题目标值“¥1,234.56”带货币符号和逗号1234.56“1 234,56”空格分隔逗号小数欧洲格式1234.56“35%”百分比0.35| “-1,234” | 负号在逗号前面 | -1234 || “12K” / “1.2万” | 缩写 | 12000 |数字清洗通用函数importredefclean_number(raw_value):ifraw_valueisNone:returnNonesstr(raw_value).strip()# 空字符串ifsors-:returnNone# 处理万if万ins:ss.replace(万,)try:returnfloat(s.replace(,,))*10000except:returnNone# 处理Kifs.upper().endswith(K):try:returnfloat(s[:-1].replace(,,))*1000except:returnNone# 处理百分比ifs.endswith(%):try:returnfloat(s[:-1])/100except:returnNone# 通用数字处理去货币符号、去逗号、去空格sre.sub(r[¥$€\s],,s)ss.replace(,,)# 千分位逗号try:returnfloat(s)except:returnNone# 确实不是数字# 使用示例print(clean_number(¥1,234.56))# 1234.56print(clean_number(35%))# 0.35print(clean_number(1.2万))# 12000.0print(clean_number(-1,234))# -1234.0temu店群自动化报活动案例清洗5日期格式统一日期格式是数据清洗里最容易翻车的环节。同一个Excel里可能出现2026-07-012026/7/17月1日2026年7月1日20260701统一处理fromdatetimeimportdatetimeimportredefclean_date(raw_value):ifraw_valueisNone:returnNonesstr(raw_value).strip()# 已经是标准格式的forfmtin[%Y-%m-%d,%Y/%m/%d,%Y%m%d]:try:returndatetime.strptime(s,fmt).strftime(%Y-%m-%d)except:pass# 中文格式s_cleans.replace(年,-).replace(月,-).replace(日,)try:returndatetime.strptime(s_clean,%Y-%m-%d).strftime(%Y-%m-%d)except:pass# 如果上面都不行尝试解析try:fromdateutilimportparser dtparser.parse(s)returndt.strftime(%Y-%m-%d)except:returnNone# 放弃标记为无效日期清洗6文本列的去噪网页上采集的文本常常带HTML标签、多余的空白、特殊字符importredefclean_text(raw_value):ifraw_valueisNone:returnsstr(raw_value)# 移除HTML标签sre.sub(r[^],,s)# 移除不可见字符零宽空格等sre.sub(r[\u200b\u200c\u200d\ufeff],,s)# 移除开头结尾的空白ss.strip()# 多个空格/换行合并成一个sre.sub(r\s, ,s)# 移除全角数字转半角可选# s s.translate(str.maketrans(, 0123456789))returns完整清洗流程组合把上面的处理串起来做成一个可复用的清洗流程# 影刀采集 → Excel → Python清洗 → 干净Excel importopenpyxlfromdatetimeimportdatetimedeffull_clean(input_file,output_file,column_rules): column_rules: { 0: text, # 第0列做文本清洗 1: number, # 第1列做数字清洗 2: date, # 第2列做日期清洗 3: None, # 第3列原样保留 } wbopenpyxl.load_workbook(input_file)wswb.active clean_data[]forrow_idx,rowinenumerate(ws.iter_rows(values_onlyTrue)):# 空行跳过ifall(cellisNoneorstr(cell).strip()forcellinrow):continuenew_rowlist(row)forcol_idx,ruleincolumn_rules.items():ifrulenumber:new_row[col_idx]clean_number(row[col_idx])elifruledate:new_row[col_idx]clean_date(row[col_idx])elifruletext:new_row[col_idx]clean_text(row[col_idx])# rule None: 原样保留clean_data.append(new_row)# 去重按第一列seenset()unique_data[]forrowinclean_data:keyrow[0]ifkeynotinseen:seen.add(key)unique_data.append(row)# 写回ws_outwb.create_sheet(Cleaned)forrowinunique_data:ws_out.append(row)wb.save(output_file)print(f清洗完成原始{ws.max_row}行 → 清洗后{len(unique_data)}行)核心要点数据清洗80%的工作量在识别脏数据只有20%在写清洗代码。先肉眼扫数据确认脏数据的模式再写代码。不要假设数据是干净的——采集回来的数据永远是脏的。作者林焱