写代码自动分析简历关键词,匹配招聘要求,颠覆海投没回音。

📅 发布时间:2026/7/15 18:36:45 👁️ 浏览次数:
写代码自动分析简历关键词,匹配招聘要求,颠覆海投没回音。
简历智能匹配系统 - 颠覆海投没回音一、实际应用场景描述目标用户数字文化艺术创新创业课程的毕业生、文化创意行业求职者、转型期职场人典型场景- 小李学完《数字艺术IP孵化》课程想投递文化科技公司产品经理岗位但不知道自己的简历哪些关键词匹配- 小王有3年传统广告经验想转行做数字文创运营海投50份简历只有2个面试不知道问题在哪- 小张应届毕业面对元宇宙内容策划、NFT运营专员等新岗位不知道如何包装自己的课程项目经历传统痛点- 关键词盲区不知道HR用ATS系统筛选哪些关键词- 匹配度模糊无法量化简历与目标岗位的契合程度- 针对性不足一份简历海投所有岗位缺乏定制化- 反馈缺失投递后石沉大海不知道哪里出了问题二、核心痛点分析痛点 影响 解决思路关键词识别不准 ATS系统直接淘汰 多维度关键词提取行业词典匹配度无法量化 不知道改进方向 余弦相似度算法技能矩阵简历内容不聚焦 核心竞争力被埋没 智能高亮缺失提醒缺乏行业洞察 错失新兴岗位机会 动态行业词库趋势分析三、核心逻辑讲解┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐│ 简历解析 │ -- │ 技能提取 │ -- │ JD解析 │ -- │ 智能匹配 │ -- │ 报告生成 ││ (PyPDF2/ │ │ (NER分词) │ │ (关键词挖掘) │ │ (相似度计算) │ │ (可视化) ││ python-docx)│ │ │ │ │ │ │ │ │└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘│ │ │ │ │▼ ▼ ▼ ▼ ▼支持PDF/DOCX 识别硬技能软技能 提取岗位核心要求 计算匹配分数 生成优化建议提取文本格式 构建个人技能画像 分析公司业务方向 生成技能矩阵 可视化展示关键技术点1. 简历解析多格式支持提取文本同时保留基础结构2. 技能提取结合命名实体识别(NER)和领域词典精准识别技能3. JD解析基于职位描述的语义分析提取硬性要求和加分项4. 智能匹配TF-IDF向量化余弦相似度量化匹配程度5. 报告生成可视化匹配结果提供具体优化建议四、代码实现项目结构resume_matcher/├── resume_matcher.py # 主程序入口├── resume_parser.py # 简历解析模块├── skill_extractor.py # 技能提取模块├── jd_analyzer.py # 职位描述分析模块├── matcher_engine.py # 智能匹配引擎├── report_generator.py # 报告生成模块├── industry_dicts.py # 行业词典模块├── config.py # 配置文件├── requirements.txt # 依赖清单└── README.md # 使用说明1. config.py - 配置文件配置参数模块包含文件路径、匹配规则、行业词典配置等# 文件路径配置RESUME_PATH input/resume.pdf # 输入简历路径JD_PATH input/job_description.txt # 职位描述文件路径OUTPUT_DIR output # 输出目录# 匹配算法配置MATCH_THRESHOLD 0.6 # 基础匹配阈值HIGH_WEIGHT_SKILLS 2.0 # 高权重技能倍数MEDIUM_WEIGHT_SKILLS 1.5 # 中权重技能倍数LOW_WEIGHT_SKILLS 1.0 # 低权重技能倍数# 行业配置CURRENT_INDUSTRY digital_culture # 当前行业SUPPORTED_INDUSTRIES [digital_culture, # 数字文化tech_product, # 科技产品creative_design, # 创意设计marketing_ops # 营销运营]# 输出配置GENERATE_REPORT True # 是否生成详细报告GENERATE_VISUALIZATION True # 是否生成可视化REPORT_FORMATS [html, json] # 报告格式# 行业词典配置INDUSTRY_DICT_PATHS {digital_culture: dicts/digital_culture_skills.txt,tech_product: dicts/tech_product_skills.txt,creative_design: dicts/creative_design_skills.txt,marketing_ops: dicts/marketing_ops_skills.txt}2. industry_dicts.py - 行业词典模块行业词典模块包含各行业的技能词库、职位词库、工具词库import osfrom typing import Dict, List, Setimport logging# 配置日志logging.basicConfig(levellogging.INFO)logger logging.getLogger(__name__)class IndustryDictionaries:行业词典管理类负责加载和管理各行业的专业词汇def __init__(self):初始化行业词典self.dicts {}self._load_default_dicts()def _load_default_dicts(self):加载默认行业词典# 数字文化行业词典self.dicts[digital_culture] {hard_skills: [# 核心技术数字艺术, IP孵化, 虚拟现实, 增强现实, 混合现实,NFT, 区块链, 元宇宙, 数字孪生, 3D建模,Unity3D, Unreal Engine, Blender, Maya, Cinema 4D,数字策展, 文化数据分析, 用户画像, 内容运营,AIGC, 生成式AI, Midjourney, Stable Diffusion, GPT,# 平台工具Steam, Roblox, Decentraland, Sandbox, OpenSea,幻核, 鲸探, 百度超级链, 蚂蚁链, 腾讯云区块链],soft_skills: [文化敏感度, 创意策划, 跨界思维, 用户洞察,内容敏感度, 审美能力, 故事叙述, IP运营思维,团队协作, 项目管理, 市场嗅觉, 创新思维],tools: [Photoshop, Illustrator, After Effects, Premiere,Figma, Sketch, Principle, ProtoPie,Python, JavaScript, HTML5, CSS3,SQL, Tableau, Power BI, Excel],positions: [数字艺术设计师, IP运营专员, 元宇宙内容策划,NFT项目经理, 数字策展人, 文创产品经理,虚拟空间设计师, AIGC应用专家, 文化数据分析师]}# 科技产品行业词典self.dicts[tech_product] {hard_skills: [产品规划, 需求分析, 原型设计, PRD撰写,敏捷开发, Scrum, Kanban, 用户研究,数据分析, AB测试, 漏斗分析, 留存分析,API设计, 数据库设计, 微服务架构, 云计算,机器学习, 深度学习, 推荐算法, 自然语言处理],soft_skills: [逻辑思维, 沟通协调, 决策能力, 抗压能力,同理心, 商业敏感度, 学习能力, 执行力],tools: [Axure, 墨刀, Figma, Sketch, Jira,Confluence, Slack, Notion, Postman,MySQL, MongoDB, Redis, Docker, Kubernetes],positions: [产品经理, 产品助理, 高级产品经理, 产品总监,技术产品经理, 数据产品经理, B端产品经理, C端产品经理]}# 创意设计行业词典self.dicts[creative_design] {hard_skills: [品牌设计, UI设计, UX设计, 视觉设计,交互设计, 动效设计, 插画设计, 字体设计,版式设计, 色彩理论, 构图技巧, 设计系统,响应式设计, 移动端设计, 网页设计, 电商设计],soft_skills: [审美能力, 创意思维, 细节把控, 趋势敏感度,客户沟通, 提案能力, 时间管理, 自我驱动],tools: [Adobe Creative Suite, Figma, Sketch, InVision,Zeplin, Abstract, Procreate, C4D,Blender, Cinema 4D, Octane, Redshift],positions: [UI设计师, UX设计师, 视觉设计师, 品牌设计师,动效设计师, 插画师, 设计主管, 创意总监]}# 营销运营行业词典self.dicts[marketing_ops] {hard_skills: [内容营销, 社交媒体运营, 社群运营, 私域运营,活动策划, 用户增长, 转化优化, SEO/SEM,数据分析, ROI分析, LTV计算, CAC分析,邮件营销, 短信营销, 短视频运营, 直播运营],soft_skills: [文案能力, 网感, 用户洞察, 数据分析思维,执行力, 创意策划, 危机公关, 跨部门协作],tools: [微信公众号, 微博, 抖音, 小红书, B站,企业微信, 钉钉, 飞书, 神策数据,GrowingIO, Google Analytics, 百度统计, 友盟],positions: [内容运营, 社群运营, 用户运营, 活动运营,新媒体运营, 增长黑客, 营销经理, 运营总监]}logger.info(f已加载{len(self.dicts)}个行业词典)def get_dict(self, industry: str) - Dict[str, List[str]]:获取指定行业的词典Args:industry: 行业名称Returns:dict: 行业词典if industry in self.dicts:return self.dicts[industry]else:logger.warning(f未找到行业词典: {industry}使用默认词典)return self.dicts[tech_product]def merge_dicts(self, industries: List[str]) - Dict[str, List[str]]:合并多个行业词典Args:industries: 行业名称列表Returns:dict: 合并后的词典merged {hard_skills: [],soft_skills: [],tools: [],positions: []}seen {hard_skills: set(),soft_skills: set(),tools: set(),positions: set()}for industry in industries:industry_dict self.get_dict(industry)for category in merged.keys():for item in industry_dict.get(category, []):if item not in seen[category]:merged[category].append(item)seen[category].add(item)logger.info(f合并词典完成共{sum(len(v) for v in merged.values())}个词条)return mergeddef add_custom_words(self, industry: str, category: str, words: List[str]):添加自定义词汇Args:industry: 行业名称category: 类别hard_skills/soft_skills/tools/positionswords: 词汇列表if industry not in self.dicts:self.dicts[industry] {hard_skills: [], soft_skills: [], tools: [], positions: []}seen set(self.dicts[industry].get(category, []))for word in words:if word not in seen:self.dicts[industry][category].append(word)seen.add(word)logger.info(f已为{industry}行业添加{len(words)}个{category}词汇)def demo_industry_dicts():演示函数dict_manager IndustryDictionaries()print( 数字文化行业硬技能 )for skill in dict_manager.dicts[digital_culture][hard_skills][:10]:print(f • {skill})print(\n 科技产品行业工具 )for tool in dict_manager.dicts[tech_product][tools][:8]:print(f • {tool})print(\n 合并数字文化科技产品词典 )merged dict_manager.merge_dicts([digital_culture, tech_product])print(f 硬技能总数: {len(merged[hard_skills])})print(f 工具总数: {len(merged[tools])})if __name__ __main__:demo_industry_dicts()3. resume_parser.py - 简历解析模块简历解析模块功能支持PDF和DOCX格式提取文本内容并保留基础结构依赖PyPDF2, python-docximport osimport refrom abc import ABC, abstractmethodfrom typing import Dict, List, Optional, Tupleimport PyPDF2from docx import Documentimport logging# 配置日志logging.basicConfig(levellogging.INFO)logger logging.getLogger(__name__)class ResumeParser(ABC):简历解析器抽象基类定义解析器的标准接口abstractmethoddef parse(self, file_path: str) - Dict:解析简历文件passabstractmethoddef extract_text(self, file_path: str) - str:提取纯文本passclass PDFResumeParser(ResumeParser):PDF格式简历解析器def __init__(self):初始化PDF解析器self.supported_extensions [.pdf]def parse(self, file_path: str) - Dict:解析PDF简历Args:file_path: PDF文件路径Returns:dict: 解析结果包含文本、结构等信息if not self._validate_file(file_path):return {success: False, error: 不支持的文件格式}try:text self.extract_text(file_path)structured_data self._extract_structured_data(text)return {success: True,text: text,structured_data: structured_data,word_count: len(text),format: PDF}except Exception as e:logger.error(fPDF解析失败: {str(e)})return {success: False, error: str(e)}def extract_text(self, file_path: str) - str:从PDF提取文本Args:file_path: PDF文件路径Returns:str: 提取的文本内容text with open(file_path, rb) as file:reader PyPDF2.PdfReader(file)for page_num, page in enumerate(reader.pages):try:page_text page.extract_text()if page_text:text f\n--- 第{page_num 1}页 ---\ntext page_textexcept Exception as e:logger.warning(f第{page_num 1}页提取失败: {str(e)})return text.strip()def _validate_file(self, file_path: str) - bool:验证文件格式_, ext os.path.splitext(file_path)return ext.lower() in self.supported_extensionsdef _extract_structured_data(self, text: str) - Dict:从文本中提取结构化数据Args:text: 纯文本Returns:dict: 结构化数据structured {contact_info: self._extract_contact_info(text),sections: self._extract_sections(text),education: self._extract_education(text),experience: self._extract_experience(text)}return structureddef _extract_contact_info(self, text: str) - Dict:提取联系信息contact {name: ,email: ,phone: ,location: ,linkedin: }# 提取邮箱email_pattern r[\w\.-][\w\.-]\.\wemails re.findall(email_pattern, text)if emails:contact[email] emails[0]# 提取手机号phone_pattern r1[3-9]\d{9}|(\\d{1,3}[- ]?)?\(?\d{1,4}\)?[- ]?\d{1,4}[- ]?\d{1,9}phones re.findall(phone_pattern, text)if phones:contact[phone] phones[0] if isinstance(phones[0], str) else phones[0][0]# 提取姓名假设在文档开头lines text.split(\n)for line in lines[:5]:line line.strip()if len(line) 2 and len(line) 20 and not re.search(r[\d], line):contact[name] linebreakreturn contactdef _extract_sections(self, text: str) - List[Dict]:提取简历章节sections []section_patterns [r^(个人简介|自我介绍|Summary|Profile),r^(工作经历|工作经验|Experience|Work History),r^(教育背景|教育经历|Education|Academic),r^(技能专长|专业技能|Skills|Competencies),r^(项目经历|项目经验|Projects|Portfolio),r^(获奖荣誉|Awards|Honors),r^(自我评价|个人评价)]compiled_patterns [re.compile(p, re.I) for p in section_patterns]lines text.split(\n)current_section Nonefor line in lines:line line.strip()if not line:continue# 检查是否是章节标题is_section Falsefor pattern in compiled_patterns:if pattern.match(line):if current_section:sections.append(current_section)current_section {title: line,content: []}is_section Truebreakif not is_section and current_section:current_section[content].append(line)if current_section:sections.append(current_section)return sectionsdef _extract_education(self, text: str) - List[Dict]:提取教育背景education []edu_pattern r([\u4e00-\u9fa5]大学|[\u4e00-\u9fa5]学院|University|College).*?(本科|硕士|博士|MBA|Bachelor|Master|PhD)matches re.finditer(edu_pattern, text, re.I)for match in matches:edu_text match.group(0)education.append({raw_text: edu_text,institution: match.group(1),degree: match.group(2)})return educationdef _extract_experience(self, text: str) - List[Dict]:提取工作经历experience []exp_pattern r(\d{4}[年/-]\d{1,2})\s*[至至-—]\s*(\d{4}[年/-]\d{1,2}|至今|present)matches list(re.finditer(exp_pattern, text))for i, match in enumerate(matches):start_date match.group(1)end_date match.group(2)# 提取时间段内的文本作为工作内容start_pos match.start()end_pos matches[i 1].start() if i 1 len(matches) else len(text)work_content text[start_pos:end_pos]experience.append({start_date: start_date,end_date: end_date,content: work_content.strip()})return experienceclass DOCXResumeParser(ResumeParser):DOCX格式简历解析器def __init__(self):初始化DOCX解析器self.supported_extensions [.docx, .doc]def parse(self, file_path: str) - Dict:解析DOCX简历Args:file_path: DOCX文件路径Returns:dict: 解析结果if not self._validate_file(file_path):return {success: False, error: 不支持的文件格式}try:doc Document(file_path)text self.extract_text(file_path)structured_data self._extract_structured_data(doc, text)return {success: True,text: text,structured_data: structured_data,word_count: len(text),format: DOCX}except Exception as e:logger.error(fDOCX解析失败: {str(e)})return {success: False, error: str(e)}def extract_text(self, file_path: str) - str:从DOCX提取文本Args:file_path: DOCX文件路径Returns:str: 提取的文本内容doc Document(file_path)text for para in doc.paragraphs:text para.text \n# 提取表格中的文本for table in doc.tables:for row in table.rows:for cell in row.cells:text cell.text text \nreturn text.strip()def _validate_file(self, file_path: str) - bool:验证文件格式_, ext os.path.splitext(file_path)return ext.lower() in self.supported_extensionsdef _extract_structured_data(self, doc, text: str) - Dict:从DOCX提取结构化数据structured {contact_info: self._extract_contact_info(text),sections: self._extract_sections(doc),education: [],experience: []}return structureddef _extract_contact_info(self, text: str) - Dict:提取联系信息复用PDF解析器的方法contact {name: ,email: ,phone: ,location: ,linkedin: }email_pattern r[\w\.-][\w\.-]\.\wemails re.findall(email_pattern, text)if emails:contact[email] emails[0]phone_pattern r1[3-9]\d{9}phones re.findall(phone_pattern, text)if phones:contact[phone] phones[0]lines text.split(\n)for line in lines[:5]:line line.strip()if len(line) 2 and len(line) 20 and not re.search(r[\d], line):contact[name] linebreakreturn contactdef _extract_sections(self, doc) - List[Dict]:从DOCX提取章节sections []current_section Nonefor para in doc.paragraphs:text para.text.strip()if not text:continue利用AI解决实际问题如果你觉得这个工具好用欢迎关注长安牧笛