Python爬虫实战:手把手教你构建工业级职业分类树形知识库!

张开发
2026/4/17 8:39:40 15 分钟阅读

分享文章

Python爬虫实战:手把手教你构建工业级职业分类树形知识库!
㊗️本期内容已收录至专栏《Python爬虫实战》持续完善知识体系与项目实战建议先订阅收藏后续查阅更方便㊙️本期爬虫难度指数⭐ (基础入门篇)福利一次订阅后专栏内的所有文章可永久免费看持续更新中保底1000(篇)硬核实战内容。全文目录 开篇语0️⃣ 前言Preface1️⃣ 摘要Abstract2️⃣ 背景与需求Why3️⃣ 合规与注意事项必写4️⃣ 技术选型与整体流程What/How5️⃣ 环境准备与依赖安装可复现6️⃣ 核心实现请求层Fetcher7️⃣ 核心实现解析层Parser8️⃣ 数据存储与导出Storage9️⃣ 运行方式与结果展示必写 常见问题与排错必写1️⃣1️⃣ 进阶优化职业树可视化1️⃣2️⃣ 总结与延伸阅读 文末✅ 专栏持续更新中建议收藏 订阅✅ 互动征集✅ 免责声明 开篇语哈喽各位小伙伴们你们好呀我是【喵手】。运营社区 C站 / 掘金 / 腾讯云 / 阿里云 / 华为云 / 51CTO欢迎大家常来逛逛一起学习一起进步我长期专注Python 爬虫工程化实战主理专栏 《Python爬虫实战》从采集策略到反爬对抗从数据清洗到分布式调度持续输出可复用的方法论与可落地案例。内容主打一个“能跑、能用、能扩展”让数据价值真正做到——抓得到、洗得净、用得上。专栏食用指南建议收藏✅ 入门基础环境搭建 / 请求与解析 / 数据落库✅ 进阶提升登录鉴权 / 动态渲染 / 反爬对抗✅ 工程实战异步并发 / 分布式调度 / 监控与容错✅ 项目落地数据治理 / 可视化分析 / 场景化应用专栏推广时间如果你想系统学爬虫而不是碎片化东拼西凑欢迎订阅专栏《Python爬虫实战》一次订阅后专栏内的所有文章可永久免费阅读持续更新中。订阅后更新会优先推送按目录学习更高效0️⃣ 前言Preface在人力资源数字化与 AI 职业导师盛行的今天一份详尽、结构化的职业分类数据是所有上层应用的“数字地基”。我们要爬什么自动化采集国家标准《职业分类大典》递归提取职业编码Code、职业名称Name、上级类别Parent Category及详细定义Definition。工具链Python 3.11Httpx(异步并发) Selectolax(基于 C 的极速解析) SQLAlchemy 2.0(ORM 模型存储)。读完获得掌握“层级编码状态机”算法实现扁平数据向树形结构的自动重构。学会处理政府/标准类网站常见的GBK 编码陷阱与长文本噪声清洗。获得一套可直接部署、具备自动重试与异常监控的生产级爬虫架构。1️⃣ 摘要Abstract本文旨在分享一套针对“职业分类大类目录页”的深度抓取与结构化重构方案。通过对职业编码规则如 1-02-03-04的规律性分析我们利用 Python 的异步生态构建了一套高性能采集流水线。重点攻克了复杂层级关联、多页面递归跳转以及大规模文本清洗等技术难题。最终产出一个符合工业标准的、具备父子自关联属性的职业知识库为 HR 系统标准化、AI 标签化及知识图谱构建提供权威数据支撑。2️⃣ 背景与需求Why为什么要费劲抓取职业分类作为一个在 HR 行业混迹多年的开发者我深知“职业名”乱象是数据分析的噩梦。职业名归一化当用户在简历里写“码农”或“Java 开发”时系统需要将其映射到标准的2-02-07-01计算机程序设计员。知识图谱构建职业是连接“技能”、“薪资”、“专业”的核心枢纽。没有标准的职业库图谱就是散沙。AI 招聘筛选大模型需要精准的职业定义来理解 JD职位描述的真实需求。目标字段清单Field Mappingocc_code: 职业编码如1-01-00-00。occ_name: 职业名称如国家机关负责人。level: 职业层级1-大类2-中类3-小类4-细类。parent_code: 上级编码通过编码规则自动计算得出。definition: 职业定义详细的功能说明文字。3️⃣ 合规与注意事项必写作为一名资深爱好者我们不仅要追求技术更要讲“码德”robots.txt此类数据通常挂在政府公开信息栏目虽具有公共属性但仍需检查协议限制。频率控制职业分类数据量通常在 2000-5000 条左右建议并发数控制在 5 以内并在请求间加入随机延迟1-3s严禁“暴力拆迁”式抓取。不绕过限制如果站点需要登录才能查阅细类请使用合法的会话信息不采集非公开的敏感内部文档。数据用途仅用于个人研究或内部系统构建请勿将原始数据直接进行商业售卖。4️⃣ 技术选型与整体流程What/How为什么不选 Scrapy 或 Selenium不选 Selenium职业分类页通常是静态或首屏渲染Selenium 太重且在处理成千上万条数据时效率极低。不选 Scrapy虽然 Scrapy 很强但对于这种“定制化解析逻辑极重”的任务手写Httpx asyncio能获得更极致的控制感。核心选型Httpx原生支持异步能完美处理 HTTP/2 协议绕过一些老旧的 WAF。Selectolax基于 C 的解析引擎。在处理长达几万行的职业目录表格时它的性能是 BeautifulSoup 的 10 倍以上。SQLAlchemy我们需要建立“自关联”树形模型ORM 是最佳选择。采集流程入口扫描抓取 8 大类第一级。递归下钻根据链接依次抓取中类、小类、细类。逻辑重构根据code长度或分隔符自动寻找其parent_code。文本治理利用 Regex 清洗混杂在定义里的特殊字符。5️⃣ 环境准备与依赖安装可复现建议在虚拟环境下操作确保生产环境纯净。项目目录结构English Filenamesoccupation_knowledge_pro/ ├── data/ # 存放数据库 ├── logs/ # 运行日志 ├── src/ │ ├── fetcher.py # 异步请求管理 │ ├── parser.py # 核心逻辑解析 │ ├── storage.py # SQLAlchemy 模型 │ └── utils.py # 工具函数 └── main.py # 入口程序安装依赖pipinstallhttpx selectolax sqlalchemy loguru tenacity pydantic6️⃣ 核心实现请求层Fetcher我们需要一个“高鲁棒性”的请求器。# src/fetcher.pyimporthttpxfromtenacityimportretry,stop_after_attempt,wait_exponentialfromloguruimportloggerclassOccupationFetcher:def__init__(self):self.headers{User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/118.0.0.0 Safari/537.36,Accept-Language:zh-CN,zh;q0.9}self.limitshttpx.Limits(max_connections5,max_keepalive_connections2)retry(stopstop_after_attempt(5),waitwait_exponential(multiplier1,min4,max10))asyncdefget_html(self,url:str):asyncwithhttpx.AsyncClient(headersself.headers,limitsself.limits,timeout15.0)asclient:try:responseawaitclient.get(url)# 应对政府网站常见的 GBK 编码ifgbinresponse.headers.get(Content-Type,).lower():response.encodinggbkresponse.raise_for_status()returnresponse.textexceptExceptionase:logger.error(f❌ Network issue on{url}:{e})raisee7️⃣ 核心实现解析层Parser这是全篇最关键的部分。职业编码如1-02-03-04本身就隐藏了父子关系。# src/parser.pyfromselectolax.lexborimportLexborHTMLParserimportreclassOccupationParser:staticmethoddefget_parent_code(current_code:str)-str:根据编码逻辑自动寻找父级partscurrent_code.split(-)iflen(parts)1:returnNonereturn-.join(parts[:-1])staticmethoddefparse_item(html_node):解析单条职业记录# 假设 HTML 结构: div classitem1-02-03-04 软件测试员 span定义.../span/divtext_contenthtml_node.text(deepTrue,stripTrue)# 利用正则精准匹配编码名称matchre.search(r([0-9-]{1,12})\s([\u4e00-\u9fa5]),text_content)ifmatch:codematch.group(1).strip(-)namematch.group(2)definitionhtml_node.css_first(.desc).text()ifhtml_node.css_first(.desc)elsereturn{occ_code:code,occ_name:name,parent_code:OccupationParser.get_parent_code(code),level:code.count(-)1,definition:definition.strip()}returnNone8️⃣ 数据存储与导出Storage使用自关联模型这能让你的数据库变得非常专业。# src/storage.pyfromsqlalchemyimportColumn,String,Integer,Text,ForeignKey,create_enginefromsqlalchemy.ormimportdeclarative_base,sessionmaker,relationship Basedeclarative_base()classOccupationEntry(Base):__tablename__occupationscodeColumn(String(20),primary_keyTrue)nameColumn(String(100),nullableFalse)levelColumn(Integer)parent_codeColumn(String(20),ForeignKey(occupations.code),nullableTrue)definitionColumn(Text)# 定义父子关联childrenrelationship(OccupationEntry,backrefparent,remote_side[code])# Database initDATABASE_FILEdata/occupation_dictionary.sqliteenginecreate_engine(fsqlite:///{DATABASE_FILE})Sessionsessionmaker(bindengine)definit_db():Base.metadata.create_all(engine)9️⃣ 运行方式与结果展示必写启动方式运行python main.py。观察logs/下生成的实时追踪日志。查看data/下生成的数据库文件。抓取结果示例Database Outputcodenamelevelparent_codedefinition2专业技术人员1NULL指在企事业单位中从事专业技术工作的人员…2-02工程技术人员22指在工程领域从事规划、设计、研发的人员…2-02-07计算机工程技术人员32-02略…2-02-07-01计算机程序设计员42-02-07从事计算机软件需求分析、设计、编码的人员… 常见问题与排错必写403 Forbidden 报错现象刚爬了几十条就被封。对策目标站有频控。将并发max_connections调低并给每个请求加一个随机的Cookie哪怕是伪造的。HTML 结构不固定现象大类是用h2写的小类是用li写的。对策在解析层增加一个“探测器”根据不同的 CSS 选择器分支处理数据。编码乱码GBK/UTF-8 混用对策使用response.content.decode(gb18030, errorsreplace)这是处理老旧中文政务站的终极杀招。1️⃣1️⃣ 进阶优化职业树可视化我们要用抓取到的数据生成一张职业层级分布图# Advanced visualization logicimportmatplotlib.pyplotaspltdefgenerate_stats_chart(data_summary):# Using English for labelslabels[Grand Class,Medium Class,Small Class,Detail Class]counts[8,75,434,1400]# Example dataplt.figure(figsize(10,6))plt.bar(labels,counts,colorskyblue)plt.title(Distribution of Occupation Hierarchy)plt.xlabel(Hierarchy Level)plt.ylabel(Number of Items)plt.savefig(data/occupational_chart.png)# English filename1️⃣2️⃣ 总结与延伸阅读通过这套工业级的爬虫架构我们不仅成功抓取了职业分类更通过编码逻辑重建了复杂的树形社会分工模型。下一步挑战你可以尝试将抓取到的“定义”文本利用jieba或HanLP进行关键词提取自动识别该职业对应的“技能标签Skills Tag”。分布式扩展如果需要抓取全国各省份的补充职业标准可以引入Redis 队列将单机爬虫扩展为分布式采集系统。 文末好啦以上就是本期的全部内容啦如果你在实践过程中遇到任何疑问欢迎在评论区留言交流我看到都会尽量回复咱们下期见小伙伴们在批阅的过程中如果觉得文章不错欢迎点赞、收藏、关注哦三连就是对我写作道路上最好的鼓励与支持❤️✅ 专栏持续更新中建议收藏 订阅墙裂推荐订阅专栏 《Python爬虫实战》本专栏秉承着以“入门 → 进阶 → 工程化 → 项目落地”的路线持续更新争取让每一期内容都做到✅ 讲得清楚原理✅ 跑得起来代码✅ 用得上场景✅ 扛得住工程化想系统提升的小伙伴强烈建议先订阅专栏 《Python爬虫实战》再按目录大纲顺序学习效率十倍上升✅ 互动征集想让我把【某站点/某反爬/某验证码/某分布式方案】等写成某期实战评论区留言告诉我你的需求我会优先安排实现(更新)哒~⭐️ 若喜欢我就请关注我叭更新不迷路⭐️ 若对你有用就请点赞支持一下叭给我一点点动力⭐️ 若有疑问就请评论留言告诉我叭我会补坑 更新迭代✅ 免责声明本文爬虫思路、相关技术和代码仅用于学习参考对阅读本文后的进行爬虫行为的用户本作者不承担任何法律责任。使用或者参考本项目即表示您已阅读并同意以下条款合法使用 不得将本项目用于任何违法、违规或侵犯他人权益的行为包括但不限于网络攻击、诈骗、绕过身份验证、未经授权的数据抓取等。风险自负 任何因使用本项目而产生的法律责任、技术风险或经济损失由使用者自行承担项目作者不承担任何形式的责任。禁止滥用 不得将本项目用于违法牟利、黑产活动或其他不当商业用途。使用或者参考本项目即视为同意上述条款,即 “谁使用谁负责” 。如不同意请立即停止使用并删除本项目。

更多文章