影刀RPA从零搭建人力资源自动化:招聘简历批量筛选系统
作者:林焱 | 适合人群:HR从业者/RPA爱好者 | 预计阅读时间:17分钟

前言
招聘旺季,HR最大的痛点是什么?
简历太多,时间太少。
一个普通职位可能收到300-500份简历,靠人工筛选,每份2分钟,全部看完就需要10-17小时。而且人工筛选还容易疲惫、标准不一致、遗漏优质候选人。

本文带你用影刀RPA搭建一套简历批量筛选系统,让机器干重复的活,HR只看筛选后的精华。
拼多多店群自动化报活动上架!
一、系统设计
功能模块

简历筛选系统
├── 简历来源接入
│ ├── 智联招聘 → 批量下载简历
│ ├── Boss直聘 → 批量下载简历
│ ├── 内推邮件 → 从邮件附件提取
│ └── 本地文件夹 → 处理已有简历
│
├── 简历解析模块
│ ├── PDF简历 → 文字提取(OCR/pdfplumber)
│ ├── Word简历 → 文字提取
│ └── 图片简历 → OCR文字识别
│
├── 智能筛选模块
│ ├── 必要条件过滤(学历/工作年限/技能)
│ ├── 加分项评分(名校/大厂/项目经验)
│ └── 综合评分排序
│
└── 输出模块
├── 分级输出Excel(A/B/C三类)
├── 向候选人发确认邮件
└── 发送筛选报告给HR负责人
二、筛选规则配置
新建screening_rules.xlsx:

Sheet1:岗位基本要求
| 岗位名称 | 最低学历 | 最低工作年限 | 必须包含技能(任一) | 排除关键词 |
|---|---|---|---|---|
| Python工程师 | 本科 | 3 | Python;Django;Flask;FastAPI | 无相关经验 |
| 产品经理 | 本科 | 2 | 产品经理;产品设计;原型;需求分析 | 兼职;在校 |
Sheet2:加分项配置
| 加分项 | 分数 | 判断方式 |
|---|---|---|
| 985/211院校 | +20 | 包含关键词 |
| BAT/头条等大厂背景 | +15 | 包含关键词 |
| 海外留学经历 | +10 | 包含关键词 |
![]() |
| 有开源项目贡献 | +10 | 包含GitHub链接 |
| 英语六级/托福 | +5 | 包含关键词 |
三、核心代码实现
模块1:从智联/招聘平台下载简历
def download_resumes_from_zhilian():
"""从智联招聘批量下载简历"""
# 登录智联招聘
打开浏览器("https://www.zhaopin.com/jobs/hr/index.html")
等待登录()
# 进入简历管理
点击("简历管理")
等待页面加载()
# 筛选条件:选择目标职位,状态=已投递未查看
选择职位("Python工程师")
选择状态("未查看")
点击("搜索")
等待加载()


# 全选并下载
点击("全选")
点击("批量下载")
# 等待打包完成
等待下载按钮出现(超时=30)
点击("下载压缩包")
# 等待文件下载到指定目录
等待文件出现("C:\\resumes\\download\\", 超时=60)
# 解压
解压文件("C:\\resumes\\download\\*.zip", "C:\\resumes\\raw\\")
写入日志(f"简历下载完成,已解压到 C:\\resumes\\raw\\")
模块2:简历文本提取
def extract_resume_text(file_path):
"""
从简历文件提取文本
支持PDF、Word、图片格式
"""
extension = 获取文件扩展名(file_path).lower()
if extension == ".pdf":
Try:
# 方法1:直接提取文字PDF
import pdfplumber
with pdfplumber.open(file_path) as pdf:
text = "\n".join(page.extract_text() or "" for page in pdf.pages)
if len(text.strip()) > 100:
return text
# 方法2:文字太少,可能是图片PDF,用OCR
text = OCR提取PDF文字(file_path)
return text
Catch as e:
写入日志(f"PDF提取失败:{file_path}: {e}")
return ""
elif extension in [".doc", ".docx"]:
import docx
doc = docx.Document(file_path)
text = "\n".join(para.text for para in doc.paragraphs)
return text
elif extension in [".jpg", ".jpeg", ".png"]:
# 图片简历,使用OCR
text = OCR识别图片(file_path)
return text
else:
写入日志(f"不支持的简历格式:{extension}")
return ""
模块3:智能筛选评分
TEMU店群矩阵自动化运营核价报活动
def screen_resume(resume_text, rules):
"""
对简历进行筛选和评分
返回:
{
"passed": True/False, # 是否通过基础筛选
"score": 75, # 综合评分(0-100)
"grade": "A", # 等级(A/B/C)
"reasons": ["...", ...], # 通过/拒绝原因
"highlights": ["...", ...] # 加分项
}
"""
reasons = []
highlights = []
base_score = 60
# ===== 基础筛选(不通过则直接拒绝)=====
# 1. 学历检查
education_levels = ["博士", "硕士", "本科", "大专", "高中"]
min_edu_index = education_levels.index(rules["min_education"])
candidate_edu = "高中" # 默认最低
for edu in education_levels:
if edu in resume_text:
candidate_edu = edu
break # 找到最高学历
candidate_edu_index = education_levels.index(candidate_edu)
if candidate_edu_index > min_edu_index: # 学历不够
return {
"passed": False,
"score": 0,
"grade": "C",
"reasons": [f"学历不符:要求{rules['min_education']},候选人{candidate_edu}"],
"highlights": []
}
# 2. 工作年限检查(提取工作年限相关信息)
import re
years_match = re.search(r'(\d+)\s*年.*工作经验', resume_text)
if years_match:
work_years = int(years_match.group(1))
if work_years < rules["min_years"]:
return {
"passed": False,
"score": 0,
"grade": "C",
"reasons": [f"工作年限不足:要求{rules['min_years']}年,候选人{work_years}年"],
"highlights": []
}
# 3. 必要技能检查
required_skills = rules["required_skills"].split(";")
found_skills = [skill for skill in required_skills if skill in resume_text]
if not found_skills:
return {
"passed": False,
"score": 0,
"grade": "C",
"reasons": [f"缺乏核心技能:需要{'/'.join(required_skills)}之一"],
"highlights": []
}
reasons.append(f"✅ 具备技能:{', '.join(found_skills)}")
base_score += len(found_skills) * 3 # 每个技能+3分
# 4. 排除关键词检查
exclude_keywords = rules["exclude_keywords"].split(";")
found_excludes = [kw for kw in exclude_keywords if kw in resume_text]
if found_excludes:
return {
"passed": False,
"score": 0,
"grade": "C",
"reasons": [f"包含排除关键词:{', '.join(found_excludes)}"],
"highlights": []
}
# ===== 加分项评分 =====
加分项列表 = [
(["清华", "北大", "复旦", "交通大学", "浙江大学", "中科大", "985", "211"], 20, "名校背景"),
(["百度", "阿里", "腾讯", "字节", "华为", "美团", "京东", "滴滴"], 15, "大厂经验"),
(["留学", "海外", "美国", "英国", "新加坡"], 10, "海外背景"),
(["github.com", "开源", "GitHub"], 10, "开源贡献"),
(["CET-6", "六级", "托福", "雅思", "英语流利"], 5, "英语能力"),
]
For keywords, score, label in 加分项列表:
if any(kw in resume_text for kw in keywords):
base_score += score
highlights.append(f"⭐ {label} (+{score}分)")
# 计算最终评分(满分100)
final_score = min(base_score, 100)
# 分级
if final_score >= 80:
grade = "A"
elif final_score >= 65:
grade = "B"
else:
grade = "C"
return {
"passed": True,
"score": final_score,
"grade": grade,
"reasons": reasons,
"highlights": highlights
}
模块4:输出结果
def export_screening_results(results, output_path):
"""将筛选结果导出为Excel"""
import openpyxl
from openpyxl.styles import PatternFill, Font
wb = openpyxl.Workbook()
# 按等级分Sheet
for grade in ["A", "B", "C", "不通过"]:
ws = wb.create_sheet(f"{grade}级候选人")
ws.append(["姓名", "文件名", "评分", "等级", "技能", "亮点", "拒绝原因"])
# 写入数据
for r in results:
sheet_name = f"{r['grade']}级候选人" if r["passed"] else "不通过"
ws = wb[sheet_name]
# 按评分用颜色标记
if r["grade"] == "A":
fill = PatternFill("solid", fgColor="92D050") # 绿色
elif r["grade"] == "B":
fill = PatternFill("solid", fgColor="FFFF00") # 黄色
else:
fill = PatternFill("solid", fgColor="FF7070") # 红色
row = ws.max_row + 1
ws.append([
r["name"],
r["file"],
r["score"],
r["grade"],
"; ".join(r["skills"]),
"; ".join(r["highlights"]),
"; ".join(r["reasons"]) if not r["passed"] else ""
])
for cell in ws[row]:
cell.fill = fill
# 删除默认Sheet
del wb["Sheet"]
wb.save(output_path)
print(f"筛选结果已保存:{output_path}")
四、系统运行效果
=== 简历筛选任务执行 ===
[09:00:01] 开始下载简历 - Python工程师职位
[09:02:15] 共下载 342 份简历(压缩包 45MB)
[09:02:30] 开始解压和文本提取...
[09:05:12] 文本提取完成(342份)
[09:05:13] 开始智能筛选...
[09:08:44] 筛选完成
=== 筛选结果摘要 ===
总简历数: 342
通过基础筛选: 156 (45.6%)
不通过: 186 (54.4%)
通过简历分级:

A级(优先面试): 38份 (24.4%)
B级(备选): 72份 (46.2%)
C级(一般): 46份 (29.5%)
主要拒绝原因:
学历不符: 89份
缺乏核心技能: 67份
工作年限不足: 30份
筛选报告已发送至:hr@company.com
耗时: 8分43秒(人工预计需要11.4小时)
总结
这套系统的核心价值:
| 对比维度 | 人工筛选 | RPA筛选 |
|---|---|---|
| 耗时 | 11.4小时 | 9分钟 |
| 一致性 | 受疲劳影响 | 完全一致 |
| 标准透明度 | 主观 | 规则可配置 |
| 审计追踪 | 无 | 完整日志 |
HR只需要配置好筛选规则,剩下的交给机器。这样HR可以把时间花在更有价值的事情上——深入了解候选人,设计更好的面试流程。

📝 本文作者:林焱 | 专注影刀RPA教程与自动化实战



2422

被折叠的 条评论
为什么被折叠?



