新Tab 精准加载 + 接口实时监听:Python 智联招聘爬虫的两种武器

发布时间:2026/7/31 9:07:36
新Tab 精准加载 + 接口实时监听:Python 智联招聘爬虫的两种武器 现代招聘平台普遍采用前后端分离架构职位数据经由 XHR 异步下发且核心字段分散于列表接口与详情接口。以requests直采静态 HTML 仅能获取渲染骨架难以保证薪资区间、HR 活跃状态等字段的完整性与保真度。本文基于 Playwright 构建采集流水线以「接口实时监听」完成字段初采以「新 Tab 精准加载」完成详情补全并引入亿牛云16yun代理 IP 分散出口形成一套可复用、抗风控的职位采集方案。一、问题建模招聘类站点的采集瓶颈可归纳为三类约束数据异步化页面 HTML 为渲染骨架真实数据来自 XHR 接口静态直采仅得空壳。字段跨接口列表接口返回职位名、公司、城市等概要字段薪资结构与 HR 在线状态通常仅由详情接口下发。上下文依赖详情接口需在「列表→详情」跳转链路中携带正确参数与referer脱离该上下文直接构造请求易触发 403 或返回空载荷。由此确立两层采集策略监听层负责发现与初采加载层负责补全与深采二者以信号量约束并发叠加代理层实现出口分散。二、武器一接口实时监听监听层通过page.on(response)在浏览器网络层挂载响应钩子接口返回即拦截 JSON 响应体并按路径特征过滤目标接口。相较于 DOM 抽取XHR 响应拦截直接获取结构化原始载荷规避渲染时序依赖与选择器脆弱性对前端结构变更具备更强鲁棒性。fromplaywright.sync_apiimportsync_playwright LIST_API_HINT/api/i/zl/zlgjdefon_response(response):ifLIST_API_HINTnotinresponse.url:returntry:payloadresponse.json()exceptException:returnjobs(payload.get(data,{}).get(list)orpayload.get(result,{}).get(list)or[])forjobinjobs:print(job.get(jobName),job.get(salary),job.get(hrStatus))withsync_playwright()asp:browserp.chromium.launch(headlessFalse,args[--disable-blink-featuresAutomationControlled])pagebrowser.new_page()page.on(response,on_response)page.goto(https://www.zhaopin.com/sou?kwPythoncity765,wait_untilnetworkidle)page.wait_for_timeout(3000)browser.close()工程要点以路径片段而非完整 URL 匹配可兼容接口版本演进networkidle配合超时以捕获懒加载触发的后续请求禁用自动化特征标志以降低被识别为自动化流量的概率。三、武器二新 Tab 精准加载加载层列表层获取jobId后模拟真实用户跳转行为为每条职位新建 Tab触发携带正确referer与业务参数的详情接口补全薪资与 HR 状态。importthreading DETAIL_API_HINT/api/i/zl/job/detailresults,lock[],threading.Lock()defcollect_detail(response):ifDETAIL_API_HINTnotinresponse.url:returntry:dresponse.json().get(data,{})exceptException:returnwithlock:results.append({jobId:d.get(jobId),salary:d.get(salary),hrActiveStatus:d.get(hrInfo,{}).get(activeStatus),hrActiveTime:d.get(hrInfo,{}).get(activeTime),})defopen_detail_tab(context,job_id):tabcontext.new_page()tab.on(response,collect_detail)tab.goto(fhttps://www.zhaopin.com/jobdetail/{job_id},wait_untilnetworkidle)tab.wait_for_timeout(1500)tab.close()新建 Tab 继承上下文的登录态与referer可规避 403单实例用毕即释放内存占用可控适配长列表的批量深采。四、组合流水线监听层填充job_index后以信号量约束并发详情 Tab 数逐条深采并合并落库。信号量本质是一种并发令牌机制在吞吐量与对端压力之间取得平衡。job_index,detail_buf{},[]lockthreading.Lock()semathreading.Semaphore(3)defdeep_collect(context,job_id):withsema:tabcontext.new_page()tab.on(response,on_detail)tab.goto(fhttps://www.zhaopin.com/jobdetail/{job_id},wait_untilnetworkidle)tab.wait_for_timeout(1200)tab.close()# on_list / on_detail 监听逻辑同前合并写入 zhilian_final.json五、数据建模薪资字段如15-25K归一为min/max/unit便于后续聚合统计HR 活跃状态online/offline配合activeTime是判定职位时效性的关键信号——HR 长期离线通常意味着投递转化率低可作为「活跃职位」过滤阈值。importredefparse_salary(raw):ifnotraw:returnNonemre.search(r(\d(?:\.\d)?)\s*[-~]\s*(\d(?:\.\d)?)\s*([Kk万]?),raw)ifnotm:returnNonelo,hi,ufloat(m.group(1)),float(m.group(2)),m.group(3)mult1000ifu.upper()Kelse(10000ifu万else1)return{min:lo*mult,max:hi*mult,currency:CNY}六、亿牛云代理出口分散与风控对抗规模化采集时单一出口 IP 的请求指纹高度集中易超出平台风控的频率阈值而触发限流乃至封禁。亿牛云16yun提供企业级代理 IP 服务按形态可分为二类隧道代理单一入口地址后端自动轮转出口节点客户端无需维护 IP 池契合高频、无状态采集。动态短效代理按存活时长如 1–5 分钟分配出口 IP支持短时会话亲和适合需维持会话状态的场景。针对本文招聘采集隧道代理最为适配——开箱即用、出口自动轮转与信号量限流协同即可在稳定性与成本间取得平衡。Playwright 通过proxy参数接入鉴权链路由代理层承载YINIU_PROXY{server:http://t.16yun.cn:31111,# 隧道代理入口以亿牛云后台为准username:YOUR_16YUN_USER,password:YOUR_16YUN_PASS,}browserp.chromium.launch(headlessFalse,proxyYINIU_PROXY,args[--disable-blink-featuresAutomationControlled])接入后监听层与加载层逻辑无需改动。若选用动态短效代理则需将 IP 列表纳入请求轮询并在会话超时后重新获取出口。实践上隧道代理按流量计费应结合限流与重试控制单位成本对多城市/多行业任务可拆分至不同隧道入口以进一步分散出口需明确的是代理仅解决出口分布问题不豁免合规义务见下节。七、稳定性与合规稳定性以信号量约束并发、引入随机请求间隔、goto设置超时与重试、已采jobId持久化以支持断点续跑代理层异常时应具备降级与告警能力。合规仅采集公开展示的职位信息不抓取求职者个人数据PII遵守robots.txt与平台用户协议控制请求频率禁止商用转售或用于不正当竞争企业内用须获授权并做脱敏处理。优先评估平台官方开放 API。八、小结监听层解决「数据从何而来」加载层解决「详情如何补全」代理层解决「出口如何分散」。三层以信号量约束并发协同运作可产出结构干净、状态可辨的职位数据集为薪资分布分析、HR 响应率评估等下游场景提供可靠的数据底座。