影刀RPA实操指南:HR场景简历自动筛选与入职流程自动化

发布时间:2026/7/28 3:16:57
影刀RPA实操指南:HR场景简历自动筛选与入职流程自动化 影刀RPA实操指南HR场景简历自动筛选与入职流程自动化HR的一天有多少时间花在操作上我老婆是HR以前每天晚上回来都跟我抱怨今天又看了200份简历眼睛要瞎了。我一开始以为是开玩笑后来她给我看了她的工作流程每天打开招聘平台Boss直聘、智联招聘、前程无忧一个一个下载新投递的简历PDF打开每份PDF看学历、工作经验、期望薪资手动记到Excel表里筛选出合适的候选人发邮件约面试面试通过后发入职资料清单收齐后再一个一个核对入职当天把候选人信息录入到OA系统、考勤系统、企业微信这些操作里除了判断简历是否合适这个决策需要人来做之外其他全是纯机械操作。一套自动化下来每天至少能省2-3个小时。我之前帮她搭了一套HR自动化系统从简历采集到入职流程全覆盖。这篇文章把完整方案整理出来换个行业背景你可以直接套用到自己的HR工作中。核心方案HR自动化五步闭环第一步简历自动采集 ├── 多平台统一采集Boss直聘/智联/前程无忧/LinkedIn ├── 批量下载简历PDF └── 自动归类存入文件夹 第二步简历信息解析与录入 ├── PDF转文本 OCR识别关键字段 ├── 自动写入Excel/飞书招聘管理表 └── 自动补充候选人评分 第三步面试安排自动化 ├── 自动发送面试邀请邮件/消息 ├── 自动创建飞书日程 └── 面试前自动提醒 第四步入职材料收集 ├── 自动发送入职资料清单 ├── 自动收件追踪 └── 资料完整度检查 第五步多系统录入 ├── 自动录入OA系统 ├── 自动开通企业微信 └── 自动创建飞书账号第一步简历自动采集HR在各个招聘平台收到的简历格式、位置都不统一。最实用的方案是从HR的邮箱入手——因为几乎所有招聘平台都会把候选人简历以邮件附件形式推送到HR邮箱。邮箱简历采集流程# 影刀Python步骤从邮箱批量下载简历附件# 适用网易邮箱/QQ邮箱/企业邮箱支持IMAP协议# 前提已开启邮箱的IMAP服务在邮箱设置中开启importimaplibimportemailfromemail.headerimportdecode_headerimportosimportre# 配置从影刀变量读取 EMAIL_ADDRESSGetVar(邮箱地址)EMAIL_PASSWORDGetVar(邮箱授权码)# 不是登录密码是邮箱设置中生成的授权码IMAP_SERVERGetVar(IMAP服务器)# 如: imap.163.com, imap.qq.comSAVE_DIRGetVar(简历存储目录)# 如: D:/简历库/SEARCH_KEYWORDS[简历,应聘,求职,Resume,CV]# 只处理最近N天的邮件DAYS_BACKint(GetVar(回溯天数))# 确保存储目录存在os.makedirs(SAVE_DIR,exist_okTrue)# 连接IMAP服务器mailimaplib.IMAP4_SSL(IMAP_SERVER)mail.login(EMAIL_ADDRESS,EMAIL_PASSWORD)mail.select(INBOX)# 搜索指定日期范围的邮件fromdatetimeimportdatetime,timedelta since_date(datetime.now()-timedelta(daysDAYS_BACK)).strftime(%d-%b-%Y)result,email_idsmail.search(None,f(SINCE {since_date}))email_id_listemail_ids[0].split()downloaded_count0foremail_idinemail_id_list:result,msg_datamail.fetch(email_id,(RFC822))raw_emailmsg_data[0][1]msgemail.message_from_bytes(raw_email)# 解析邮件主题subject,encodingdecode_header(msg[Subject])[0]ifisinstance(subject,bytes):subjectsubject.decode(encodingorutf-8,errorsignore)# 判断是否是简历邮件is_resume_mailFalseforkeywordinSEARCH_KEYWORDS:ifkeyword.lower()in(subjector).lower():is_resume_mailTruebreakifnotis_resume_mail:continue# 解析发件人from_strmsg.get(From,)# 尝试提取姓名和邮箱from_namefrom_email_addrmatchre.search(r?([^]*)?\s*([^]),from_str)ifmatch:from_namematch.group(1).strip()from_email_addrmatch.group(2).strip()# 遍历附件forpartinmsg.walk():ifpart.get_content_maintype()multipart:continueifpart.get(Content-Disposition)isNone:continuefilenamepart.get_filename()iffilename:# 解码文件名filename,encodingdecode_header(filename)[0]ifisinstance(filename,bytes):filenamefilename.decode(encodingorutf-8,errorsignore)# 只下载简历格式PDF/Wordifnotany(filename.lower().endswith(ext)forextin[.pdf,.doc,.docx]):continue# 构建保存的文件名日期_候选人姓名_原文件名safe_from_namere.sub(r[\\/*?:|],,from_nameor未知)save_namef{datetime.now().strftime(%Y%m%d)}_{safe_from_name}_{filename}save_pathos.path.join(SAVE_DIR,save_name)# 保存附件withopen(save_path,wb)asf:f.write(part.get_payload(decodeTrue))downloaded_count1print(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 pdfplumberimportPyPDF2importpdfplumberimportreimportjsonimportos resume_dirGetVar(简历存储目录)results[]# 遍历下载的简历PDFforfilenameinos.listdir(resume_dir):ifnotfilename.endswith(.pdf):continuefilepathos.path.join(resume_dir,filename)full_text# 方法1先用pdfplumber提取对表格格式更好try:withpdfplumber.open(filepath)aspdf:forpageinpdf.pages:page_textpage.extract_text()ifpage_text:full_textpage_text\nexcept:pass# 方法2如果pdfplumber没提取到文本用PyPDF2ifnotfull_text.strip():try:withopen(filepath,rb)asf:readerPyPDF2.PdfReader(f)forpageinreader.pages:full_textpage.extract_text()\nexcept:pass# 方法3如果还是空的用影刀的OCR指令单独处理ifnotfull_text.strip():print(f文本提取失败建议用OCR处理:{filename})continue# 关键信息提取 # 1. 提取姓名通常在简历开头2-4个中文字符# 简历第一行经常是姓名取前几行中符合规则的linesfull_text.strip().split(\n)nameforlineinlines[:5]:lineline.strip()# 匹配2-4个中文字符且不包含常见非姓名关键词ifre.match(r^[\u4e00-\u9fa5]{2,4}$,line):ifnotany(kwinlineforkwin[简历,个人,联系,男,女,应聘]):namelinebreak# 如果第一行没提取到尝试用姓名关键词定位ifnotname:name_matchre.search(r姓名[:\s]*([\u4e00-\u9fa5]{2,4}),full_text)namename_match.group(1)ifname_matchelse# 2. 提取手机号phonephone_matchre.search(r1[3-9]\d{9},full_text)phonephone_match.group()ifphone_matchelse# 3. 提取邮箱email_addremail_matchre.search(r[\w.-][\w-]\.[\w.],full_text)email_addremail_match.group()ifemail_matchelse# 4. 提取学历educationedu_patterns[博士,硕士,本科,大专,中专,高中]forlevelinedu_patterns:iflevelinfull_text:educationlevel# 尝试提取学校名称学历关键词前后20字范围内的学校相关词edu_posfull_text.find(level)nearbyfull_text[max(0,edu_pos-30):edu_pos30]school_matchre.search(r([\u4e00-\u9fa5]{2,10}(大学|学院|学校)),nearby)ifschool_match:educationf{school_match.group(1)}{level}break# 5. 提取工作年限experienceexp_matchre.search(r(\d)[\s-]*年.*?经验,full_text)ifexp_match:experiencef{exp_match.group(1)}年else:# 或者从工作经历的时间跨度推算year_rangesre.findall(r(\d{4})\s*[.\-/至到]\s*(\d{4}|至今|今),full_text)ifyear_ranges:start_yearmin(int(y[0])foryinyear_ranges)total_years2026-start_year# 当前年份experiencef约{total_years}年# 6. 提取期望薪资expected_salarysalary_matchre.search(r(期望|意向|薪资要求|薪酬).*?(\d)[kK千]?\s*[-~至]\s*(\d)[kK千]?,full_text)ifsalary_match:expected_salaryf{salary_match.group(2)}K-{salary_match.group(3)}Kelse:# 只提取单一数字salary_singlere.search(r(期望|意向).*?(\d)[kK千],full_text)ifsalary_single:expected_salaryf{salary_single.group(2)}K# 7. 提取应聘职位positionposition_matchre.search(r(求职意向|应聘|意向岗位|期望职位)[:\s]*([\u4e00-\u9fa5a-zA-Z/]{2,20}),full_text)positionposition_match.group(2)ifposition_matchelsefilename.split(_)[1]if_infilenameelseresults.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_asciiFalse))SetVar(解析简历数,len(results))print(f简历解析完成共{len(results)}份)forrinresults:print(f{r[姓名]}|{r[学历]}|{r[工作经验]}|{r[期望薪资]}|{r[应聘职位]})第三步写入飞书招聘管理表将解析结果写入飞书多维表格HR可以在表格中直接进行筛选、打分、安排面试。飞书Base招聘管理表字段设计字段类型说明候选人姓名文本自动提取手机号文本自动提取邮箱文本自动提取学历单选博士/硕士/本科/大专/其他工作经验文本如3年期望薪资文本如15K-20K应聘职位单选按职位预设选项简历附件附件上传简历PDF面试状态单选待筛选/已邀约/一面/二面/已通过/已拒绝面试时间日期时间安排的面试时间HR评分数字1-5分备注多行文本HR手动填写第四步面试自动安排筛选出合适的候选人后自动发送面试邀请邮件并创建飞书日程。# 影刀Python步骤发送面试邀请邮件 创建飞书日程importsmtplibfromemail.mime.textimportMIMETextfromemail.mime.multipartimportMIMEMultipartimportjsonimportrequestsfromdatetimeimportdatetime,timedelta# 邮件配置 SMTP_SERVERGetVar(SMTP服务器)# 如: smtp.163.comSMTP_PORTint(GetVar(SMTP端口))# 如: 465 (SSL)EMAIL_ADDRESSGetVar(发送邮箱)EMAIL_PASSWORDGetVar(邮箱授权码)# 候选人数据 candidatesjson.loads(GetVar(待发邀请候选人))interview_dateGetVar(面试日期)# 如: 2024-07-15interview_timeGetVar(面试时间)# 如: 14:00interview_locationGetVar(面试地点)# 或线上会议链接forcandidateincandidates:# 发送面试邀请邮件 msgMIMEMultipart()msg[From]EMAIL_ADDRESS msg[To]candidate[邮箱]msg[Subject]f面试邀请 -{candidate[应聘职位]}-{candidate[姓名]}# 邮件正文bodyf{candidate[姓名]}您好 感谢您投递{candidate[应聘职位]}职位经过简历筛选我们诚挚邀请您参加面试。 面试时间{interview_date}{interview_time}面试方式{线下面试地址interview_locationifinterview_locationelse线上面试会议链接将在面试前发送}预计时长约30-60分钟 请回复本邮件确认是否参加如有时间冲突可沟通调整。 期待与您的交流 --- 此邮件由RPA自动发送请勿回复。如有疑问请联系HR。 msg.attach(MIMEText(body,plain,utf-8))try:serversmtplib.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}exceptExceptionase:print(f发送失败:{candidate[姓名]}:{e})candidate[面试状态]发送失败SetVar(邀请发送结果,json.dumps(candidates,ensure_asciiFalse))第五步入职资料收集自动化面试通过后需要收集候选人的入职资料身份证、学历证书、离职证明等。资料清单自动推送模板入职资料清单 □ 身份证正反面复印件 □ 学历/学位证书复印件 □ 离职证明原件 □ 银行卡信息工资卡 □ 一寸照片电子版 □ 体检报告 □ 入职登记表已附在邮件中 请在{截止日期}前将所有电子版发送至HR邮箱纸质版可入职当天携带。完整流程编排定时任务每日8:00、14:00各执行一次 │ ├─→ 步骤1采集新简历 │ ├─ 登录招聘平台下载最新简历 │ └─ 检查邮箱下载新到的简历附件 │ ├─→ 步骤2简历解析 │ ├─ 逐份解析PDF关键信息 │ └─ 写入飞书招聘管理表 │ ├─→ 步骤3自动初筛可选 │ ├─ 学历不满足条件 → 自动标记不合适 │ ├─ 工作经验不足 → 自动标记不合适 │ └─ 合适 → 标记待筛选提醒HR查看 │ ├─→ 步骤4HR手动筛选人工操作 │ └─ HR在飞书表中查看并打分 │ ├─→ 步骤5发送面试邀请 │ ├─ 对已通过筛选的候选人 │ ├─ 自动发送面试邀请邮件 │ └─ 自动创建飞书面试日历 │ ├─→ 步骤6面试前提醒定时任务 │ ├─ 面试前一天 → 发送提醒邮件给候选人 │ └─ 面试当天 → 飞书消息提醒面试官 │ └─→ 步骤7入职资料收集 ├─ 面试通过后自动发送资料清单 ├─ 定期检查是否收齐 └─ 资料不全时自动催办常见问题速查问题1PDF简历文本提取不出来全是空白现象pdfplumber和PyPDF2都提取不到文字。原因有些简历是扫描版的图片格式或者用了特殊字体编码。解决方式用影刀的OCR指令提取文本设置识别语言为中文或者用百度OCR的PDF识别API# 百度OCR处理扫描版PDFfromaipimportAipOcr ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/f58277ccf1d7467ca15f189367fe51e9.png#pic_center)clientAipOcr(APP_ID,API_KEY,SECRET_KEY)resultclient.pdf_ocr(pdf_path)问题2候选人姓名解析错误比如把联系方式识别为名字现象解析结果中的姓名栏显示的是联系方式、个人简历等无关文字。原因PDF提取文本的前几行可能包含非姓名内容。解决方式增加姓名验证规则——匹配到的文本必须全是中文字符长度2-4个且不在排除词列表中exclude_names[简历,个人,联系,求职,应聘,自我,在线,联系方式]问题3Boss直聘等平台的简历没有直接的下载按钮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飞书日历APIhttps://open.feishu.cn/document/server-docs/calendar-v4/calendar/introduction邮箱IMAP服务开启指南网易/QQ/企业微信邮箱帮助中心内容标签#影刀RPA #HR自动化 #简历筛选 #招聘自动化 #入职流程 #飞书 #OCR #Python作者林焱| 影刀RPA深度使用者两年以上实操经验 | 专注于企业办公自动化涵盖HR、财务、行政等领域