爬虫

一、整体设计思路

这套爬虫是一个多站点、生产级的招聘数据采集系统,不是简单的脚本,而是有完整的工程化设计。核心分三层:

基类(spider.py)→ 各平台子类(spider_liepin/yupao/51job)→ 远端服务集群

spider_architecture-a8aec172

二、基类 Spider 做了什么

spider.py 是所有爬虫的父类,封装了所有平台通用的能力:

1. 配置管理:启动时读 spider.ini,拿到 Chrome 路径、代理列表、各接口地址等,子类直接继承就能用。

2. 代理 IP 管理:不是本地硬编码代理,而是调用远端 getProxy 接口动态获取,并记录每个代理的使用次数和状态(setProxyRecord)。代理被封了就换一个,实现了代理池的动态调度。

3. 本地文件系统:初始化时自动建好目录结构 —— job/com/success/failed/progress/clean/ 等。数据先落磁盘,再异步入库,入库成功就 shutil.movesuccess/,失败就移到 failed/这是关键设计:断网、崩溃都不丢数据。

4. 入库通信insert() 方法把抓到的 JSON 用 HTTP POST 发给远端 comparse/jobparse 接口,有重试机制(最多 maxTryTime 次)。

5. 去重判断traverseFolder() 遍历本地文件目录,判断某个公司或职位是否在 6 个月内(timeInterval=15552000 秒)抓过,避免重复抓取。


三、子类的核心技术:Playwright + 接口拦截

以猎聘(spider_liepin.py)为例,这是最典型的思路:

为什么用 Playwright 而不是直接请求接口? 因为猎聘有反爬,需要模拟真实浏览器操作。但聪明的地方在于它并不靠 DOM 解析拿数据,而是:

page.on('response', self.onResponese)  # 监听所有网络响应

onResponse 里只捕获特定 API 接口的响应(api-c.liepin.com/...pc-search-job),直接拿 JSON。这叫接口拦截,比解析 DOM 稳定得多。

反检测措施

  • 注入 JS 覆盖 navigator.webdriver,让网站无法识别自动化工具
  • 过滤掉图片/字体/媒体资源(__handleRequest),节省流量提高速度
  • 随机 sleep(randomSleep)模拟人工操作节奏

条件组合抓取__getSpiderConditions() 把 公司性质 × 公司规模 × 工作经验 做笛卡尔积,生成几百个条件组合,每个组合对应一次筛选+翻页抓取。每次执行前 random.shuffle(conditions) 打乱顺序,降低被识别为机器的风险。


四、反封机制

系统在几个层面做了防封:

机制 实现方式
代理轮换 每次抓取前动态获取新代理,每个代理限量使用(maxSpiderCount=500
随机延迟 random.randint(3,8) 秒随机等待
浏览器伪装 禁用 webdriver 特征,启用 --disable-blink-features=AutomationControlled
错误恢复 被 405 了就换代理重启,超限了就休眠到明天 8 点

五、鱼泡的不同之处

鱼泡(spider_yupao.py)有个额外设计:spiderDateEnd 配置,支持按时间范围抓取(比如只抓今天或某个日期之后的数据),适合增量抓取场景。


项目分区导航00-Python与爬虫总览 ⬅️ | 01-爬虫架构总览 | ➡️ 爬虫系统建设