Python爬虫实战:手把手教你职业分类大类全层级自动化采集与标准化实战!

张开发
2026/4/11 23:44:16 15 分钟阅读

分享文章

Python爬虫实战:手把手教你职业分类大类全层级自动化采集与标准化实战!
㊗️本期内容已收录至专栏《Python爬虫实战》持续完善知识体系与项目实战建议先订阅收藏后续查阅更方便㊙️本期爬虫难度指数⭐ (基础入门篇)福利一次订阅后专栏内的所有文章可永久免费看持续更新中保底1000(篇)硬核实战内容。全文目录 开篇语0️⃣ 前言Preface1️⃣ 摘要Abstract2️⃣ 背景与需求Why3️⃣ 合规与注意事项Mandatory Compliance4️⃣ 技术选型与整体流程What/How5️⃣ 环境准备与依赖安装Environment6️⃣ 核心实现请求层Fetcher7️⃣ 核心实现解析层Parser8️⃣ 数据存储与导出Storage9️⃣ 运行方式与结果展示Operation 常见问题与排错Troubleshooting1️⃣1️⃣ 进阶优化Optimization1️⃣2️⃣ 总结与延伸阅读 文末✅ 专栏持续更新中建议收藏 订阅✅ 互动征集✅ 免责声明 开篇语哈喽各位小伙伴们你们好呀我是【喵手】。运营社区 C站 / 掘金 / 腾讯云 / 阿里云 / 华为云 / 51CTO欢迎大家常来逛逛一起学习一起进步我长期专注Python 爬虫工程化实战主理专栏 《Python爬虫实战》从采集策略到反爬对抗从数据清洗到分布式调度持续输出可复用的方法论与可落地案例。内容主打一个“能跑、能用、能扩展”让数据价值真正做到——抓得到、洗得净、用得上。专栏食用指南建议收藏✅ 入门基础环境搭建 / 请求与解析 / 数据落库✅ 进阶提升登录鉴权 / 动态渲染 / 反爬对抗✅ 工程实战异步并发 / 分布式调度 / 监控与容错✅ 项目落地数据治理 / 可视化分析 / 场景化应用专栏推广时间如果你想系统学爬虫而不是碎片化东拼西凑欢迎订阅专栏《Python爬虫实战》一次订阅后专栏内的所有文章可永久免费阅读持续更新中。订阅后更新会优先推送按目录学习更高效0️⃣ 前言Preface在数字化招聘与人才画像领域职业编码是所有算法的“通用语言”。无论是构建技能图谱还是实现跨平台职位对齐一份详尽、准确的职业分类目录是不可或缺的基石。本文将带你通过 Python 深入拆解职业分类网站利用httpx的异步性能与lxml的解析精度构建一个能够自动识别父子级关系、补全编码链路的智能爬虫。读完本指南你将获得多级嵌套解析方案攻克从“大类”到“细类”的递归抓取难题。编码校验逻辑自动识别并纠正非标准职业编码。知识库前置表建模学习如何设计支持递归查询的 SQL 表结构。1️⃣ 摘要Abstract本文旨在提供一套完整的职业分类数据采集方案。通过分析目标站点的层级加载机制通常为树形结构我们采用Async-Pipeline异步流水线技术配合XPath 深度优先搜索DFS算法实现对职业名称、编码及定义的精准抽取。核心技术点Context-Aware Parser:解析器能够感知当前所处的层级深度。Data Integrity Check:针对长篇定义的自动化清洗与去噪。High-Performance Storage:使用 SQLite 的递归视图存储层级数据。2️⃣ 背景与需求Why为什么要爬取职业分类简历解析Resume Parsing作为标准词库用于从非结构化简历中提取职业标签。行业洞察分析新职业如“人工智能训练师”在目录中的归属观察产业变迁。ERP/HRMS 系统为企业内部人事管理系统提供标准化的下拉选择菜单。目标字段清单Field ListFieldNameTypeDescriptionjob_code职业编码String如1-01-01 (大类-中类-小类)job_name职业名称String如行政办事人员parent_code上级类别String关联父级 job_codedefinition职业定义Text从事…工作的人员job_level层级深度Integer1:大类, 2:中类, 3:小类, 4:细类3️⃣ 合规与注意事项Mandatory Compliance公开性原则职业大典属于国家标准类政务公开信息通常允许公众查询但需注意版权归属。并发抑制职业目录数据量较大数千条建议并发数控制在 5 以内单次抓取间隔 0.5s避免触发 WAF 的频率封禁。非侵入式严禁抓取带有用户权限或内部未公开的申报流程数据。4️⃣ 技术选型与整体流程What/How逻辑难点很多职业目录页面的“定义”是点击后弹窗显示或异步加载的。如果是同步页面我们用httpx如果是异步渲染我们要抓取其内部 API。Flowchart (Technical Architecture):5️⃣ 环境准备与依赖安装Environment目录结构建议Job_Classification_Project/ ├── engine/ │ ├── scraper_core.py # 异步请求引擎 │ └── tree_parser.py # 树形解析逻辑 ├── storage/ │ └── db_handler.py # SQLite 操作 ├── main.py # 统一入口 └── outputs/ # 导出文件存放依赖安装pipinstallhttpx lxml loguru pandas6️⃣ 核心实现请求层Fetcher对于这种具有深层链接的结构我们需要一个连接池Connection Pool。importhttpximportasynciofromloguruimportloggerclassJobFetcher:def__init__(self):# 模拟高版本 Chrome防止被识别为爬虫self.headers{User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36,Referer:http://www.mohrss.gov.cn/}self.limitshttpx.Limits(max_connections5,max_keepalive_connections2)self.clienthttpx.AsyncClient(headersself.headers,limitsself.limits,timeout20.0)asyncdeffetch_safe(self,url:str):try:# 增加随机延迟避免频率过快awaitasyncio.sleep(0.5)responseawaitself.client.get(url)ifresponse.status_code200:returnresponse.text logger.warning(f⚠️ Unexpected status{response.status_code}for{url})exceptExceptionase:logger.error(f❌ Network issue:{e})returnNone7️⃣ 核心实现解析层Parser这是处理“层级关系”最关键的地方。我们要确保每个子项都能正确继承父级的编码。fromlxmlimportetreeclassTreeParser:staticmethoddefparse_list_items(html_content):解析当前页面的职业列表treeetree.HTML(html_content)items[]# 假设每一行是一个 tr包含编码、名称、操作链接rowstree.xpath(//table[classjob-table]//tr[position()1])forrowinrows:code.join(row.xpath(./td[1]//text())).strip()name.join(row.xpath(./td[2]//text())).strip()# 获取详情链接进入下一层或查看定义detail_urlrow.xpath(./td[3]/a/href)[0]items.append({code:code,name:name,url:detail_url})returnitemsstaticmethoddefparse_definition(detail_html):从详情页提取定义字段treeetree.HTML(detail_html)# 清理多余的空格和换行raw_deftree.xpath(//div[classdefinition-box]//text())clean_def .join([t.strip()fortinraw_defift.strip()])returnclean_def8️⃣ 数据存储与导出Storage为了方便后续做“职业树”展示我们在 SQLite 中使用parent_code建立关联。importsqlite3classJobStorage:def__init__(self,db_fileoccupational_standard.sqlite):self.connsqlite3.connect(db_file)self._init_db()def_init_db(self):self.conn.execute( CREATE TABLE IF NOT EXISTS job_tree ( id INTEGER PRIMARY KEY AUTOINCREMENT, job_code TEXT UNIQUE, job_name TEXT, parent_code TEXT, definition TEXT, level INTEGER ) )# 索引优化方便层级查询self.conn.execute(CREATE INDEX IF NOT EXISTS idx_parent ON job_tree(parent_code))defupsert_job(self,data):sql INSERT INTO job_tree (job_code, job_name, parent_code, definition, level) VALUES (?, ?, ?, ?, ?) ON CONFLICT(job_code) DO UPDATE SET definitionexcluded.definition self.conn.execute(sql,data)self.conn.commit()9️⃣ 运行方式与结果展示Operation执行流程说明启动main.py。爬虫首先抓取 8 个大类。进入每个大类抓取中类。递归直至细类并保存定义。展示示例 (Database Preview):job_codejob_nameparent_codedefinitionlevel1党的机关、国家机关…人员0履行国家公职…的人员11-01中国共产党机关负责人1在中国共产党各级机关…21-01-01中央机关负责人1-01在中央机关及其工作机构…3 常见问题与排错Troubleshooting编码不一致有些老旧页面编码是10101有些是1-01-01。建议在存储前统一格式化为带短横线的标准格式。定义缺失某些大类只有名称没有定义。解析时需增加if not definition: definition 见子项描述的补全逻辑。递归陷阱如果页面结构存在循环引用极少见需建立visited_urls集合防止死循环。1️⃣1️⃣ 进阶优化OptimizationBreadcrumb Recovery:如果详情页丢失了父级信息可以通过解析页面的“面包屑导航Breadcrumbs”来反向回溯parent_code。Vectorization:将definition字段通过 Sentence-Transformer 转化为向量存入向量数据库实现“根据工作内容描述匹配职业编码”的功能。1️⃣2️⃣ 总结与延伸阅读通过对职业分类大类的抓取我们成功构建了一个层次分明、关系紧密的知识库底表。这不仅锻炼了我们处理树形结构数据的能力也为后续的 NLP 任务提供了高质量的语料。复盘收获实现了深度优先的递归抓取逻辑。掌握了 SQLite 层级索引的优化技巧。学会了在复杂排版中提取结构化定义的清洗方案。 文末好啦以上就是本期的全部内容啦如果你在实践过程中遇到任何疑问欢迎在评论区留言交流我看到都会尽量回复咱们下期见小伙伴们在批阅的过程中如果觉得文章不错欢迎点赞、收藏、关注哦三连就是对我写作道路上最好的鼓励与支持❤️✅ 专栏持续更新中建议收藏 订阅墙裂推荐订阅专栏 《Python爬虫实战》本专栏秉承着以“入门 → 进阶 → 工程化 → 项目落地”的路线持续更新争取让每一期内容都做到✅ 讲得清楚原理✅ 跑得起来代码✅ 用得上场景✅ 扛得住工程化想系统提升的小伙伴强烈建议先订阅专栏 《Python爬虫实战》再按目录大纲顺序学习效率十倍上升✅ 互动征集想让我把【某站点/某反爬/某验证码/某分布式方案】等写成某期实战评论区留言告诉我你的需求我会优先安排实现(更新)哒~⭐️ 若喜欢我就请关注我叭更新不迷路⭐️ 若对你有用就请点赞支持一下叭给我一点点动力⭐️ 若有疑问就请评论留言告诉我叭我会补坑 更新迭代✅ 免责声明本文爬虫思路、相关技术和代码仅用于学习参考对阅读本文后的进行爬虫行为的用户本作者不承担任何法律责任。使用或者参考本项目即表示您已阅读并同意以下条款合法使用 不得将本项目用于任何违法、违规或侵犯他人权益的行为包括但不限于网络攻击、诈骗、绕过身份验证、未经授权的数据抓取等。风险自负 任何因使用本项目而产生的法律责任、技术风险或经济损失由使用者自行承担项目作者不承担任何形式的责任。禁止滥用 不得将本项目用于违法牟利、黑产活动或其他不当商业用途。使用或者参考本项目即视为同意上述条款,即 “谁使用谁负责” 。如不同意请立即停止使用并删除本项目。

更多文章