直接用正则匹配薪资常为空,因HTML结构混乱、格式多样(如“15K-25K”“面议”“1.2万/月”),单一正则如r'\d+-\d+'会漏单值、带单位或年薪条目;需先清洗文本、再分步提取并归一化数值,最后用IQR等方法过滤异常值。

为什么直接用正则匹配薪资经常拿到空结果
招聘网站的薪资字段 HTML 结构混乱,常见形式如 "15K-25K"、"面议"、"8000-12000元/月"、"20k·14薪",甚至混有空格、中文顿号、斜杠。正则若只写 r'\d+-\d+',会漏掉单值(如 "18K")、带单位(如 "1.2万")、含年薪标识的条目。
真正有效的做法是分三步清洗:先统一文本为小写并替换中文符号,再提取所有可能的数字片段,最后按上下文判断是否为月薪数值。例如把 "1.5万-2万/月" → "15000-20000",再拆成两个整数。
- 避免用
re.search(r'(\d+)-(\d+)', text)直接捕获——它不匹配"25K"这类单值 - 优先用
re.findall(r'[\d.]+[kK\u4e07]?', text)提取带单位的数字块,再逐个标准化 - 遇到
"面议"、"薪资面谈"等明确无数字的字段,直接跳过,别强行转0
如何把“15K-25K”、“8K”、“1.2万”统一转成月薪整数
关键不是一步正则搞定,而是建立一个转换函数,对每个匹配到的原始字符串做归一化处理。重点在于识别单位(K、k、万)和数量级,并区分是否含“年薪”字样(如 "20k·15薪" 要除以 12)。
示例函数逻辑:
立即学习“Python免费学习笔记(深入)”;
def parse_salary(s):
s = s.strip().lower().replace(' ', '')
if '面议' in s or 'negotiable' in s:
return None
# 提取数字部分(支持小数、带k/万)
num_match = re.search(r'([\d.]+)([kK\u4e07]?)', s)
if not num_match:
return None
num, unit = float(num_match.group(1)), num_match.group(2)
# 单位换算
if unit == 'k' or unit == 'K':
base = int(num * 1000)
elif unit == '万' or unit == '\u4e07':
base = int(num * 10000)
else:
base = int(num)
# 检查是否含年薪线索(如“14薪”、“年薪”字样)
if '年薪' in s or '·' in s and any(c in s for c in ['薪', 'x']):
base = base // 12
return base
- 注意
re.search比re.findall更适合单值提取,避免误抓“联系人电话”里的数字 - 不要用
float()直接转"1.5万"——必须先分离数字和单位 - 实际采集中,建议对每个页面薪资字段单独调用该函数,返回
None的条目不参与后续统计
计算平均值前必须过滤异常值
爬下来的数据里常混入明显错误值:比如 "3K"(可能是实习生岗但被误标为正式岗)、"99999"(爬虫错位抓到 ID 或时间戳)、"0"(解析失败填充的默认值)。直接求均值会让结果严重失真。
- 用四分位距(IQR)法过滤:计算 Q1、Q3,剔除
< Q1 - 1.5×IQR或> Q3 + 1.5×IQR的值 - 设定业务合理区间,如初级岗位排除
< 4000或> 30000的值(根据城市和职位调整) - 保留原始字符串与解析后数值的映射关系,出问题时可快速定位是哪类 HTML 结构导致解析偏差
绕过反爬时,正则提取比 CSS 选择器更稳定吗
不是更稳定,而是更底层、更容错。当网站频繁改 class 名或 DOM 结构时,BeautifulSoup.select('.salary-text') 会大面积失效;而正则作用于原始 HTML 字符串,只要薪资数字还在页面源码里,哪怕被包在 <div data-v-xxx> 或注释中,也能靠模式匹配捞出来。
- 但代价是:必须用
response.text而非response.json()——现在很多招聘站用 Ajax 加载数据,得先找到真实接口(如/api/job/search),再对返回 JSON 中的salary字段做正则 - 不要在未解密的 JS 文件里硬扒薪资——有些站点把数字拆成数组再拼接,正则无法还原
- 如果目标站用了字体图标或 canvas 渲染薪资,正则完全无效,此时需 OCR 或逆向字体映射,不属于本方案范畴
真正难的从来不是写对一行正则,而是确认你拿到的 HTML 片段确实包含未经混淆的明文薪资数字——这步验证比写代码花的时间多得多。


















