影刀RPA实操指南:HR场景简历自动筛选与入职流程自动化
HR的一天,有多少时间花在"操作"上?
我老婆是HR,以前每天晚上回来都跟我抱怨:"今天又看了200份简历,眼睛要瞎了。"我一开始以为是开玩笑,后来她给我看了她的工作流程:
这些操作里,除了"判断简历是否合适"这个决策需要人来做之外,其他全是纯机械操作。一套自动化下来,每天至少能省2-3个小时。
我之前帮她搭了一套HR自动化系统,从简历采集到入职流程全覆盖。这篇文章把完整方案整理出来,换个行业背景,你可以直接套用到自己的HR工作中。

核心方案:HR自动化五步闭环
第一步:简历自动采集
├── 多平台统一采集(Boss直聘/智联/前程无忧/LinkedIn)
├── 批量下载简历PDF
└── 自动归类存入文件夹
第二步:简历信息解析与录入
├── PDF转文本 + OCR识别关键字段
├── 自动写入Excel/飞书招聘管理表
└── 自动补充候选人评分
第三步:面试安排自动化
├── 自动发送面试邀请邮件/消息
├── 自动创建飞书日程
└── 面试前自动提醒
第四步:入职材料收集
├── 自动发送入职资料清单
├── 自动收件追踪
└── 资料完整度检查
第五步:多系统录入
├── 自动录入OA系统
├── 自动开通企业微信
└── 自动创建飞书账号
第一步:简历自动采集
HR在各个招聘平台收到的简历格式、位置都不统一。最实用的方案是从HR的邮箱入手——因为几乎所有招聘平台都会把候选人简历以邮件附件形式推送到HR邮箱。
邮箱简历采集流程
# 影刀Python步骤:从邮箱批量下载简历附件
# 适用:网易邮箱/QQ邮箱/企业邮箱(支持IMAP协议)
# 前提:已开启邮箱的IMAP服务(在邮箱设置中开启)
import imaplib
import email
from email.header import decode_header
import os
import re
# ========== 配置(从影刀变量读取) ==========
EMAIL_ADDRESS = GetVar('邮箱地址')
EMAIL_PASSWORD = GetVar('邮箱授权码') # 不是登录密码,是邮箱设置中生成的授权码
IMAP_SERVER = GetVar('IMAP服务器') # 如: imap.163.com, imap.qq.com
SAVE_DIR = GetVar('简历存储目录') # 如: D:/简历库/
SEARCH_KEYWORDS = ['简历', '应聘', '求职', 'Resume', 'CV']
# 只处理最近N天的邮件
DAYS_BACK = int(GetVar('回溯天数'))
# 确保存储目录存在
os.makedirs(SAVE_DIR, exist_ok=True)
# 连接IMAP服务器
mail = imaplib.IMAP4_SSL(IMAP_SERVER)
mail.login(EMAIL_ADDRESS, EMAIL_PASSWORD)
mail.select('INBOX')
# 搜索指定日期范围的邮件
from datetime import datetime, timedelta
since_date = (datetime.now() – timedelta(days=DAYS_BACK)).strftime('%d-%b-%Y')
result, email_ids = mail.search(None, f'(SINCE "{since_date}")')
email_id_list = email_ids[0].split()
downloaded_count = 0
for email_id in email_id_list:
result, msg_data = mail.fetch(email_id, '(RFC822)')
raw_email = msg_data[0][1]
msg = email.message_from_bytes(raw_email)
# 解析邮件主题
subject, encoding = decode_header(msg['Subject'])[0]
if isinstance(subject, bytes):
subject = subject.decode(encoding or 'utf-8', errors='ignore')
# 判断是否是简历邮件
is_resume_mail = False
for keyword in SEARCH_KEYWORDS:
if keyword.lower() in (subject or '').lower():
is_resume_mail = True
break
if not is_resume_mail:
continue
# 解析发件人
from_str = msg.get('From', '')
# 尝试提取姓名和邮箱
from_name = ''
from_email_addr = ''
match = re.search(r'"?([^"<]*)"?\\s*<([^>]+)>', from_str)
if match:
from_name = match.group(1).strip()
from_email_addr = match.group(2).strip()
# 遍历附件
for part in msg.walk():
if part.get_content_maintype() == 'multipart':
continue
if part.get('Content-Disposition') is None:
continue
filename = part.get_filename()
if filename:
# 解码文件名
filename, encoding = decode_header(filename)[0]
if isinstance(filename, bytes):
filename = filename.decode(encoding or 'utf-8', errors='ignore')
# 只下载简历格式:PDF/Word
if not any(filename.lower().endswith(ext) for ext in ['.pdf', '.doc', '.docx']):
continue
# 构建保存的文件名:日期_候选人姓名_原文件名
safe_from_name = re.sub(r'[\\\\/*?:"<>|]', '', from_name or '未知')
save_name = f"{datetime.now().strftime('%Y%m%d')}_{safe_from_name}_{filename}"
save_path = os.path.join(SAVE_DIR, save_name)
# 保存附件
with open(save_path, 'wb') as f:
f.write(part.get_payload(decode=True))
downloaded_count += 1
print(f'下载: {save_name}')
mail.logout()
SetVar('下载简历数', downloaded_count)
print(f'简历采集完成,共下载{downloaded_count}份')
招聘平台页面直接采集(备选方案)
有些HR习惯直接在招聘平台页面上下载简历。各平台的简历列表页面结构:
拼多多店群自动化报活动上架!
# Boss直聘 – 沟通中的人才列表
//div[contains(@class,'chat-record-item')] # 候选人卡片
.//span[contains(@class,'name')] # 候选人姓名
.//span[contains(@class,'job-name')] # 应聘职位
.//a[contains(text(),'查看简历')] # 简历链接
# 前程无忧 – 收到的简历列表
//div[contains(@class,'resume-item')] # 简历行
.//span[contains(@class,'name-text')] # 姓名
.//a[contains(@class,'download')] # 下载按钮
# 智联招聘 – 应聘简历列表
//div[contains(@class,'apply-item')] # 应聘记录行
第二步:简历信息解析
下载简历PDF后,需要提取关键信息。这块用影刀内置OCR或者Python的PDF解析库来处理。
# 影刀Python步骤:简历PDF解析与关键信息提取
# 依赖:pip install PyPDF2 pdfplumber
import PyPDF2
import pdfplumber
import re
import json
import os
resume_dir = GetVar('简历存储目录')
results = []
# 遍历下载的简历PDF
for filename in os.listdir(resume_dir):
if not filename.endswith('.pdf'):
continue
filepath = os.path.join(resume_dir, filename)
full_text = ''
# 方法1:先用pdfplumber提取(对表格格式更好)
try:
with pdfplumber.open(filepath) as pdf:
for page in pdf.pages:
page_text = page.extract_text()
if page_text:
full_text += page_text + '\\n'
except:
pass
# 方法2:如果pdfplumber没提取到文本,用PyPDF2
if not full_text.strip():
try:
with open(filepath, 'rb') as f:
reader = PyPDF2.PdfReader(f)
for page in reader.pages:
full_text += page.extract_text() + '\\n'
except:
pass
# 方法3:如果还是空的,用影刀的OCR指令单独处理
if not full_text.strip():
print(f'文本提取失败,建议用OCR处理: {filename}')
continue
# ========== 关键信息提取 ==========
# 1. 提取姓名(通常在简历开头,2-4个中文字符)
# 简历第一行经常是姓名,取前几行中符合规则的
lines = full_text.strip().split('\\n')
name = ''
for line in lines[:5]:
line = line.strip()
# 匹配2-4个中文字符,且不包含常见非姓名关键词
if re.match(r'^[\\u4e00-\\u9fa5]{2,4}$', line):
if not any(kw in line for kw in ['简历', '个人', '联系', '男', '女', '应聘']):
name = line
break
# 如果第一行没提取到,尝试用"姓名"关键词定位
if not name:
name_match = re.search(r'姓名[::\\s]*([\\u4e00-\\u9fa5]{2,4})', full_text)
name = name_match.group(1) if name_match else ''
# 2. 提取手机号
phone = ''
phone_match = re.search(r'1[3-9]\\d{9}', full_text)
phone = phone_match.group() if phone_match else ''
# 3. 提取邮箱
email_addr = ''
email_match = re.search(r'[\\w.+-]+@[\\w-]+\\.[\\w.]+', full_text)
email_addr = email_match.group() if email_match else ''
# 4. 提取学历
education = ''
edu_patterns = ['博士', '硕士', '本科', '大专', '中专', '高中']
for level in edu_patterns:
if level in full_text:
education = level
# 尝试提取学校名称(学历关键词前后20字范围内的学校相关词)
edu_pos = full_text.find(level)
nearby = full_text[max(0, edu_pos–30):edu_pos+30]
school_match = re.search(r'([\\u4e00-\\u9fa5]{2,10}(大学|学院|学校))', nearby)
if school_match:
education = f'{school_match.group(1)} {level}'
break
# 5. 提取工作年限
experience = ''
exp_match = re.search(r'(\\d+)[\\s-]*年.*?经验', full_text)
if exp_match:
experience = f'{exp_match.group(1)}年'
else:
# 或者从工作经历的时间跨度推算
year_ranges = re.findall(r'(\\d{4})\\s*[.\\-/至到]\\s*(\\d{4}|至今|今)', full_text)
if year_ranges:
start_year = min(int(y[0]) for y in year_ranges)
total_years = 2026 – start_year # 当前年份
experience = f'约{total_years}年'
# 6. 提取期望薪资
expected_salary = ''
salary_match = re.search(r'(期望|意向|薪资要求|薪酬).*?(\\d+)[kK千]?\\s*[-~至]\\s*(\\d+)[kK千]?', full_text)
if salary_match:
expected_salary = f'{salary_match.group(2)}K-{salary_match.group(3)}K'
else:
# 只提取单一数字
salary_single = re.search(r'(期望|意向).*?(\\d+)[kK千]', full_text)
if salary_single:
expected_salary = f'{salary_single.group(2)}K'
# 7. 提取应聘职位
position = ''
position_match = re.search(r'(求职意向|应聘|意向岗位|期望职位)[::\\s]*([\\u4e00-\\u9fa5a-zA-Z+/]{2,20})', full_text)
position = position_match.group(2) if position_match else filename.split('_')[1] if '_' in filename else ''
results.append({
'姓名': name,
'手机': phone,
'邮箱': email_addr,
'学历': education,
'工作经验': experience,
'期望薪资': expected_salary,
'应聘职位': position,
'简历来源': filename,
'简历路径': filepath,
'解析时间': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'面试状态': '待筛选',
'评分': ''
})
SetVar('简历解析结果', json.dumps(results, ensure_ascii=False))
SetVar('解析简历数', len(results))
print(f'简历解析完成,共{len(results)}份')
for r in results:
print(f' {r["姓名"]} | {r["学历"]} | {r["工作经验"]} | {r["期望薪资"]} | {r["应聘职位"]}')
第三步:写入飞书招聘管理表
将解析结果写入飞书多维表格,HR可以在表格中直接进行筛选、打分、安排面试。
飞书Base招聘管理表字段设计:
| 候选人姓名 | 文本 | 自动提取 |
| 手机号 | 文本 | 自动提取 |
| 邮箱 | 文本 | 自动提取 |
| 学历 | 单选 | 博士/硕士/本科/大专/其他 |
| 工作经验 | 文本 | 如:3年 |
| 期望薪资 | 文本 | 如:15K-20K |
| 应聘职位 | 单选 | 按职位预设选项 |
| 简历附件 | 附件 | 上传简历PDF |
| 面试状态 | 单选 | 待筛选/已邀约/一面/二面/已通过/已拒绝 |
| 面试时间 | 日期时间 | 安排的面试时间 |
| HR评分 | 数字 | 1-5分 |
| 备注 | 多行文本 | HR手动填写 |
第四步:面试自动安排
筛选出合适的候选人后,自动发送面试邀请邮件并创建飞书日程。

# 影刀Python步骤:发送面试邀请邮件 + 创建飞书日程
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import json
import requests
from datetime import datetime, timedelta
# ========== 邮件配置 ==========
SMTP_SERVER = GetVar('SMTP服务器') # 如: smtp.163.com
SMTP_PORT = int(GetVar('SMTP端口')) # 如: 465 (SSL)
EMAIL_ADDRESS = GetVar('发送邮箱')
EMAIL_PASSWORD = GetVar('邮箱授权码')
# ========== 候选人数据 ==========
candidates = json.loads(GetVar('待发邀请候选人'))
interview_date = GetVar('面试日期') # 如: 2024-07-15
interview_time = GetVar('面试时间') # 如: 14:00
interview_location = GetVar('面试地点') # 或线上会议链接
for candidate in candidates:
# === 发送面试邀请邮件 ===
msg = MIMEMultipart()
msg['From'] = EMAIL_ADDRESS
msg['To'] = candidate['邮箱']
msg['Subject'] = f'面试邀请 – {candidate["应聘职位"]} – {candidate["姓名"]}'
# 邮件正文
body = f"""{candidate['姓名']},您好!
感谢您投递{candidate['应聘职位']}职位,经过简历筛选,我们诚挚邀请您参加面试。
面试时间:{interview_date} {interview_time}
面试方式:{'线下面试,地址:' + interview_location if interview_location else '线上面试,会议链接将在面试前发送'}
预计时长:约30-60分钟
请回复本邮件确认是否参加,如有时间冲突可沟通调整。
期待与您的交流!
—
此邮件由RPA自动发送,请勿回复。如有疑问请联系HR。
"""
msg.attach(MIMEText(body, 'plain', 'utf-8'))
try:
server = smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT)
server.login(EMAIL_ADDRESS, EMAIL_PASSWORD)
server.sendmail(EMAIL_ADDRESS, candidate['邮箱'], msg.as_string())
server.quit()
print(f'面试邀请已发送: {candidate["姓名"]} ({candidate["邮箱"]})')
# 更新状态
candidate['面试状态'] = '已邀约'
candidate['面试时间'] = f'{interview_date} {interview_time}'
except Exception as e:
print(f'发送失败: {candidate["姓名"]}: {e}')
candidate['面试状态'] = '发送失败'
SetVar('邀请发送结果', json.dumps(candidates, ensure_ascii=False))
第五步:入职资料收集自动化
面试通过后,需要收集候选人的入职资料(身份证、学历证书、离职证明等)。
资料清单自动推送模板:
入职资料清单:
□ 身份证正反面复印件
□ 学历/学位证书复印件
□ 离职证明原件
□ 银行卡信息(工资卡)
□ 一寸照片电子版
□ 体检报告
□ 入职登记表(已附在邮件中)
请在{截止日期}前将所有电子版发送至HR邮箱,纸质版可入职当天携带。

完整流程编排
定时任务(每日8:00、14:00各执行一次)
│
├─→ 步骤1:采集新简历
│ ├─ 登录招聘平台下载最新简历
│ └─ 检查邮箱,下载新到的简历附件
│
├─→ 步骤2:简历解析
│ ├─ 逐份解析PDF关键信息
│ └─ 写入飞书招聘管理表
│
├─→ 步骤3:自动初筛(可选)
│ ├─ 学历不满足条件 → 自动标记"不合适"
│ ├─ 工作经验不足 → 自动标记"不合适"
│ └─ 合适 → 标记"待筛选",提醒HR查看
│
├─→ 步骤4:HR手动筛选(人工操作)
│ └─ HR在飞书表中查看并打分
│
├─→ 步骤5:发送面试邀请
│ ├─ 对"已通过筛选"的候选人
│ ├─ 自动发送面试邀请邮件
│ └─ 自动创建飞书面试日历
│
├─→ 步骤6:面试前提醒(定时任务)
│ ├─ 面试前一天 → 发送提醒邮件给候选人
│ └─ 面试当天 → 飞书消息提醒面试官
│
└─→ 步骤7:入职资料收集
├─ 面试通过后自动发送资料清单
├─ 定期检查是否收齐
└─ 资料不全时自动催办
常见问题速查
问题1:PDF简历文本提取不出来(全是空白)
现象:pdfplumber和PyPDF2都提取不到文字。 原因:有些简历是扫描版的(图片格式),或者用了特殊字体编码。 解决方式:
- 用影刀的OCR指令提取文本(设置识别语言为中文)
- 或者用百度OCR的PDF识别API:# 百度OCR处理扫描版PDF
from aip import AipOcr
client = AipOcr(APP_ID, API_KEY, SECRET_KEY)
result = client.pdf_ocr(pdf_path)
问题2:候选人姓名解析错误(比如把"联系方式"识别为名字)
现象:解析结果中的姓名栏显示的是"联系方式"、"个人简历"等无关文字。 原因:PDF提取文本的前几行可能包含非姓名内容。 解决方式:增加姓名验证规则——匹配到的文本必须全是中文字符,长度2-4个,且不在排除词列表中:
exclude_names = ['简历', '个人', '联系', '求职', '应聘', '自我', '在线', '联系方式']
问题3:Boss直聘等平台的简历没有直接的下载按钮
TEMU店群矩阵自动化运营核价报活动
现象:Boss直聘的简历需要"查看"而不是下载,无法直接获取PDF。 原因:部分平台为了保护候选人隐私,简历是分片展示的。 解决方式:
- 用影刀的"网页截图"截取完整简历页面,保存为PDF
- 或者手动一个个浏览,采集页面上的文本信息(不推荐,效率低)
- 另一个方案:在Boss直聘上引导候选人将简历发送到指定邮箱
问题4:发送面试通知邮件被判定为垃圾邮件

现象:发出的面试邀请邮件都被邮箱系统归类到垃圾箱。 原因:短时间内大量发送相似内容的邮件,触发反垃圾机制。 解决方式:
- 每封邮件之间间隔5-10秒
- 不要使用纯HTML格式,使用纯文本格式更具个人化感觉
- 重要候选人手动发送,自动化仅处理初级筛选
问题5:入职资料追了半天,候选人说"没收到"
现象:发了资料清单邮件,候选人说没收到,结果资料交得晚。 原因:邮件可能进垃圾箱,或者候选人没及时查看。 解决方式:
- 邮件 + 短信双通道通知(短信可通过阿里云短信服务API发送)
- 在飞书Base中跟踪资料收集进度,逾期自动发送催办消息
- 加入"已读回执"功能(技术上有局限,不做强制要求)
问题6:不同招聘平台的简历格式差异太大
现象:Boss直聘导出的PDF和前程无忧导出的PDF结构完全不同,提取规则很难统一。 原因:各平台简历模板不同。 
解决方式:
- 不要试图用一套规则覆盖所有平台,按平台分表处理
- 把简历文件名中加入平台标识(如Boss直聘_姓名.pdf)
- 建立平台→字段映射配置表,每个平台单独维护提取规则
推荐资源
- Python PDF解析:PyPDF2 / pdfplumber / reportlab
- 百度OCR PDF识别:https://cloud.baidu.com/product/ocr
- 飞书日历API:https://open.feishu.cn/document/server-docs/calendar-v4/calendar/introduction
- 邮箱IMAP服务开启指南(网易/QQ/企业微信邮箱帮助中心)
内容标签
#影刀RPA #HR自动化 #简历筛选 #招聘自动化 #入职流程 #飞书 #OCR #Python

作者:林焱 | 影刀RPA深度使用者,两年以上实操经验 | 专注于企业办公自动化,涵盖HR、财务、行政等领域 







