
影刀RPA新手教程数据校验与质量检查实战——采集完就知道数据是否准确采集1000条数据50条价格为空30条重复——不做校验等于白干我第一次做完电商数据采集信心满满把数据交给同事做分析结果同事说——50条价格为空、30条重复数据、还有几条价格范围写反了min比max还大。数据质量一塌糊涂分析结果全是垃圾。从那以后我养成了一个习惯采集完必须跑校验生成质量报告有问题就告警。数据校验不是可有可无的后处理它是采集流程的必做步骤。校验四个维度——完整性、合法性、一致性、去重验证每个维度都有具体可操作的检查方法。安装与影刀环境影刀安装走官网下载64位版本。数据校验主要用Python pandas影刀内嵌Python环境直接import pandas就行——不需要额外安装。但影刀的Python环境版本可能比较旧如果pandas不可用用影刀的【从文本中提取内容】指令做正则校验也能凑合。影刀的Excel操作指令够用——【打开Excel】【读取数据表格内容】【写入Excel行】【筛选Excel】这些指令是校验流程的基础。元素定位——校验流程也要抓元素数据校验不是纯数据处理有时候需要回到源网站验证数据准确性。比如怀疑某条价格数据不对要回到电商页面重新抓取验证。校验场景的元素定位和采集一样四合一定位策略XPath定位——精确校验单个元素比如某条商品的价格CSS选择器——批量校验列表数据正则匹配——从文本中提取数字做比对捕获元素——快速验证单个页面影刀的【获取元素文本】指令配合XPath能快速抓取单个字段的值用于比对# 回源网站验证价格actual_pricebrowser.get_element(//span[contains(class,price)],modexpath).get_text()影刀还提供了【从文本中提取内容】指令内置多种正则提取模式——提取数字、提取手机号、提取Email、提取身份证号。做合法性校验时非常实用不用写正则选个模式就行。自定义正则提取——当内置模式不够用时# 影刀的【从文本中提取内容】指令# 提取方式选自定义内容输入正则表达式# 提取价格范围的数字: r(\d)-(\d)# 提取日期: r\d{4}-\d{2}-\d{2}# 提取URL: rhttps?://[\w./-]正则表达式在元素定位中也有用处——影刀的元素编辑支持正则匹配属性值。比如某个元素的class属性是price_active_12abc用正则^((?!disabled).)*$可以匹配不含disabled的所有class值。变量与数据类型——校验结果的数据结构校验结果用字典结构存储包含四个维度的检测结果validation_result{completeness:{# 完整性empty_fields:{price:50,title:3,url:0},row_count:1000,expected_rows:1000},legality:{# 合法性invalid_format:{date:12,phone:5},invalid_range:{price_below_zero:3,price_above_max:0}},consistency:{# 一致性logic_conflict:{min_gt_max:7,start_after_end:0}},deduplication:{# 去重duplicate_count:30,duplicate_ids:[id_123,id_456,...]},total_issues:107,quality_score:89.3# 100分满分}变量类型转换是校验的核心问题——采集数据全是文本类型做数值校验前必须转换采集原始值类型校验需要类型转换方法“15-25K”strint正则提取int()“2024-01-15”strdatetimedatetime.strptime()“99.5”strfloatfloat()“”strNoneif not val: None“NULL”strNoneval.replace(‘NULL’, ‘’)踩坑点——float()转换99.5元会报错因为元不是数字。先用正则提取纯数字部分再转换。流程控制——校验流程的分支判断数据校验流程用If条件判断做分支处理影刀的If指令支持多种条件文本包含/不包含数字大于/小于/等于变量为空/不为空正则匹配/不匹配校验流程的核心分支结构采集完成 → 读取Excel数据 → 完整性检查(空值判断) → 合法性检查(格式判断) → 一致性检查(逻辑判断) → 去重检查(ID重复判断) → 生成质量报告 → If判断: 问题率10%? → 告警暂停 → 正常继续ForEach循环遍历每行数据做逐条校验# 逐行校验模板issues[]foridx,rowinenumerate(data_rows):# 完整性必填字段为空ifnotrow.get(price)orrow[price]:issues.append({row:idx1,field:price,type:empty})# 合法性价格是否是有效数字try:price_valfloat(re.sub(r[^\d.],,row[price]))ifprice_val0:issues.append({row:idx1,field:price,type:negative})exceptValueError:issues.append({row:idx1,field:price,type:invalid_format})# 一致性min_price max_priceifrow.get(min_price)androw.get(max_price):iffloat(row[min_price])float(row[max_price]):issues.append({row:idx1,field:price_range,type:min_gt_max})# 去重ID是否重复ifrow[id]inseen_ids:issues.append({row:idx1,field:id,type:duplicate})seen_ids.add(row[id])While循环用于动态校验——一边采集一边校验实时发现问题# 采集校验并行流程whilehas_next_page:page_datacollect_page(browser)page_issuesvalidate_page(page_data)iflen(page_issues)5:# 单页问题太多可能页面有问题system.print_log(第{}页数据异常过多暂停采集.format(current_page))breakall_data.extend(page_data)all_issues.extend(page_issues)网页自动化——回源校验的完整操作回源校验是指回到数据来源网站重新抓取怀疑有问题的数据做比对。步骤从质量报告中提取有问题的数据ID列表逐个打开对应的网页用原始URL或搜索定位重新抓取该条数据比对原始采集值和新抓取值如果不一致更新为新值fromxbotimportweb,systemdefrevalidate_item(browser,original_url,original_data):回源验证单条数据browser.get(original_url)system.sleep(2)# 重新抓取各字段actual_titlebrowser.get_element(//h1[contains(class,product-name)],modexpath).get_text()actual_pricebrowser.get_element(//span[contains(class,price)],modexpath).get_text()# 比对differences{}ifactual_title!original_data[title]:differences[title]{original:original_data[title],actual:actual_title}ifactual_price!original_data[price]:differences[price]{original:original_data[price],actual:actual_price}returndifferences回源校验的成本比较高——1000条数据全部回源验证要花很长时间。建议只对问题数据做回源验证没问题的不用重查。数据处理——pandas批量校验最快逐行用If判断做校验太慢1000条数据要跑很久。用pandas批量校验1秒出结果。importpandasaspdimportnumpyasnpdefvalidate_with_pandas(file_path):pandas批量数据校验dfpd.read_excel(file_path)report{}# 1. 完整性检查 # 必填字段为空的行数required_fields[id,title,price,date]empty_counts{}forfieldinrequired_fields:# pandas判断空值NaN、None、空字符串empty_maskdf[field].isna()|(df[field])|(df[field]NULL)empty_counts[field]int(empty_mask.sum())report[empty_fields]empty_counts report[row_count]len(df)# 2. 合法性检查 # 价格是否是数字price_numericpd.to_numeric(df[price].str.replace(r[^\d.],,regexTrue),errorscoerce)invalid_priceprice_numeric.isna().sum()# 价格范围检查negative_price(price_numeric0).sum()extreme_price(price_numeric999999).sum()# 日期格式检查date_parsedpd.to_datetime(df[date],errorscoerce)invalid_datedate_parsed.isna().sum()report[legality]{invalid_price_format:int(invalid_price),negative_price:int(negative_price),extreme_price:int(extreme_price),invalid_date_format:int(invalid_date)}# 3. 一致性检查 # min_price max_price 的逻辑冲突min_colpd.to_numeric(df[min_price],errorscoerce)max_colpd.to_numeric(df[max_price],errorscoerce)logic_conflict(min_colmax_col).sum()report[consistency]{min_gt_max:int(logic_conflict)}# 4. 去重检查 duplicate_countdf.duplicated(subsetid,keepFalse).sum()duplicate_idsdf[df.duplicated(subsetid,keepFalse)][id].unique().tolist()report[deduplication]{duplicate_count:int(duplicate_count),duplicate_ids:duplicate_ids}# 汇总 total_issuessum(empty_counts.values())int(invalid_pricenegative_priceextreme_priceinvalid_datelogic_conflictduplicate_count)quality_scoreround(100-(total_issues/len(df)*100),1)report[total_issues]total_issues report[quality_score]quality_scorereturnreportpandas校验比逐行If判断快50倍以上。1000条数据pandas处理不到1秒逐行判断要50秒。这是数据校验的首选方式。踩坑点——pandas的pd.to_numeric()加了errorscoerce’参数后无法转换的值变成NaN而不是报错。这对校验来说刚好好用——NaN数量就是格式错误数量。鼠标键盘图像自动化——校验流程的辅助操作数据校验偶尔用到鼠标键盘操作主要是两个场景截图保存问题数据——在源网页上截取有问题的数据区域存为图片证据OCR识别图片中的数据——有些网站的价格是图片而非文字用OCR提取做校验截图保存——影刀的【截屏】指令截取指定窗口区域fromxbotimportsystem# 截取网页问题区域system.screenshot(region{x:100,y:200,width:300,height:150},save_pathD:/validation/screenshots/issue_row_{}.png.format(row_idx))OCR校验——用影刀的百度OCR模块识别图片中的文字数据和采集数据比对fromxbotimportai ocrai.baidu.BaiduAI(api_keyxxx,secret_keyxxx)ocr_resultocr.ocr_from_file(D:/validation/screenshots/price.png)# ocr_result是字符串列表拼接后和采集数据比对ocr_price.join(ocr_result)OCR在数据校验中不是最常用但在特定场景图片价格、图片验证码很有用。了解就行不是每条数据都要OCR。键盘操作——CtrlF在网页上搜索特定ID做回源定位比手动翻页快。进阶技能——Python脚本HTTP请求正则校验数据校验的进阶技能组合——Python脚本做批量校验HTTP请求验证URL有效性正则做格式校验。URL有效性校验——采集的URL字段是否是可访问的网页fromxbotimportwebdefvalidate_urls(url_list,timeout5):批量验证URL是否有效invalid_urls[]forurlinurl_list:try:responseweb.http_get(url,timeouttimeout)# 200-299状态码都是有效的ifresponse.status_code300:invalid_urls.append(url)exceptException:invalid_urls.append(url)returninvalid_urls正则校验大全——常用字段的正则表达式字段正则说明手机号r’^1[3-9]\d{9}$’1开头3-99位数字Emailr’1[\w.-].\w$’基本格式日期r’^\d{4}-\d{2}-\d{2}$’YYYY-MM-DD价格r’^\d.?\d*$’数字可选小数URLr’^https?/[\w./-]$’http/https开头ID号r’^\d{6,20}$’6-20位纯数字影刀的【从文本中提取内容】指令封装了这些常用正则不需要自己写。选择对应的提取方式就行——提取数字、提取手机号码、提取Email。ADB是安卓端操作模块数据校验不需要ADB。了解就行。平台实战——电商招聘双平台校验数据校验在不同平台的侧重点不同维度电商数据校验重点招聘数据校验重点完整性价格为空、商品名为空薪资为空、公司名为空合法性价格非数字、日期格式错薪资格式错、经验年限异常一致性minmax价格反了min_salarymax_salary去重同一商品ID重复同一职位ID重复电商数据的常见问题价格为空——促销页价格藏在弹窗里采集时没点到弹窗就空了价格含单位——99.5元不是纯数字校验时会报格式错误日期格式混乱——有2024-01-15也有01/15/2024还有20240115同一SKU重复——不同页码出现同一商品招聘数据的常见问题薪资面议——没有数值校验时标记为空薪资格式不统一——“15-25K和15k-25k和15000-25000”地点格式混乱——“北京·朝阳区和北京市朝阳区”同一职位重复发布——同一公司同一职位在多天发布双平台校验流程架构主流程 → 选择数据源(电商/招聘) → 读取Excel数据 → 平台特定校验(电商:价格校验 / 招聘:薪资校验) → 通用校验(完整性合法性一致性去重) → 生成质量报告 → If判断: 问题率阈值 → 告警 / 继续系统联动——校验完自动告警修复校验结果出来后要做三件事——告警、修复、记录。告警——问题率超过10%就发钉钉或邮件告警fromxbotimportmail issue_ratereport[total_issues]/report[row_count]*100ifissue_rate10:mail.send(todata_teamemail.com,subject数据质量告警: 问题率{}%.format(round(issue_rate,1)),body完整性问题: {}\n合法性问题: {}\n一致性问题: {}\n重复数据: {}.format(report[empty_fields],report[legality],report[consistency],report[deduplication][duplicate_count]))修复——自动化修复常见数据问题问题自动修复方式价格为空回源网站重新抓取价格含单位正则提取纯数字日期格式不统一datetime.strptime统一格式minmax交换min和max重复数据pandas.drop_duplicates()按ID去重NULL字符串替换为None或空# 自动修复模板defauto_fix(df):自动修复常见数据问题# 价格去单位df[price]df[price].str.replace(r[^\d.],,regexTrue)df[price]pd.to_numeric(df[price],errorscoerce)# 日期格式统一df[date]pd.to_datetime(df[date],errorscoerce).dt.strftime(%Y-%m-%d)# minmax交换swap_maskdf[min_price]df[max_price]df.loc[swap_mask,[min_price,max_price]]df.loc[swap_mask,[max_price,min_price]].values# 去重dfdf.drop_duplicates(subsetid,keepfirst)returndf质量报告写入——用影刀的Excel指令把报告写入独立文件fromxbotimportexcel# 创建质量报告Excelreport_wbexcel.create(D:/validation/quality_report.xlsx)report_wb.write_row(1,[检查维度,问题类型,问题数量,问题详情])report_wb.write_row(2,[完整性,价格为空,50,行3,行7,行15,...])report_wb.write_row(3,[合法性,价格格式错,12,行5,行9,...])report_wb.save()工程化与规范——校验流程标准化数据校验是每个采集项目的必做步骤标准化后能直接复用校验规则配置化——每个项目的校验规则放在validate_config.json里校验脚本模块化——完整性、合法性、一致性、去重各封装成子流程报告格式统一——所有项目使用相同的质量报告模板告警阈值可配置——不同项目的问题率阈值不同# 校验配置文件结构config{project:ecommerce_price,required_fields:[id,title,price,date],numeric_fields:[price,min_price,max_price],date_fields:[date],unique_fields:[id],alert_threshold:10,# 问题率超过10%告警auto_fix:True# 是否自动修复}命名规范——校验文件用validate_项目名.json格式质量报告用report_项目名_日期.xlsx格式。更详细的校验规则配置和自动化修复方案可以参考 home.linyan.cloud 上分享的数据质量检查工具源码。速查表与常见报错报错原因解决pd.read_excel()报错文件不存在或格式错确认路径用openpyxl引擎pd.to_numeric()全变NaN原始数据有文字混入先用str.replace清理再转换正则提取返回空列表匹配模式不对用影刀的【从文本中提取内容】测试正则| 校验结果全是0 | 字段名和实际列名不一致 | 先用df.columns确认列名 || 去重后数据量不对 | keep参数选错 | keepfirst’保留第一条,keepFalse全删 || 质量分数为负数 | 问题数数据行数 | 检查是否有重复统计 |关键速查完整性df[field].isna() | (df[field] ‘’)合法性pd.to_numeric(df[field], errors‘coerce’).isna()一致性(df[‘min’] df[‘max’]).sum()去重df.duplicated(subset‘id’, keepFalse).sum()自动修复df.drop_duplicates(subset‘id’, keep‘first’)价格清理df[‘price’].str.replace(r’[^\d.], ‘’, regexTrue)告警判断issue_rate total_issues / row_count * 100正则提取影刀【从文本中提取内容】指令采集1000条数据自动跑校验发现50条价格为空30条重复生成质量报告89.3分。校验流程标准化后每个新项目只需要改配置文件不用重写校验逻辑。#影刀RPA #新手教程 #数据校验 #质量检查 #pandas #数据清洗 #自动化修复作者林焱\w.- ↩︎