--- title: "01-爬虫架构总览" created: 2026-04-01 tags: - 项目 aliases: - 爬虫架构总览 --- # 爬虫 ## 一、整体设计思路 这套爬虫是一个**多站点、生产级的招聘数据采集系统**,不是简单的脚本,而是有完整的工程化设计。核心分三层: **基类(spider.py)→ 各平台子类(spider\_liepin/yupao/51job)→ 远端服务集群** ![[spider_architecture-a8aec172.svg]] --- ## 二、基类 Spider 做了什么 `spider.py` 是所有爬虫的父类,封装了所有平台通用的能力: **1. 配置管理**:启动时读 `spider.ini`,拿到 Chrome 路径、代理列表、各接口地址等,子类直接继承就能用。 **2. 代理 IP 管理**:不是本地硬编码代理,而是调用远端 `getProxy` 接口动态获取,并记录每个代理的使用次数和状态(`setProxyRecord`)。代理被封了就换一个,实现了代理池的动态调度。 **3. 本地文件系统**:初始化时自动建好目录结构 —— `job/`、`com/`、`success/`、`failed/`、`progress/`、`clean/` 等。数据先落磁盘,再异步入库,入库成功就 `shutil.move` 到 `success/`,失败就移到 `failed/`。**这是关键设计**:断网、崩溃都不丢数据。 **4. 入库通信**:`insert()` 方法把抓到的 JSON 用 HTTP POST 发给远端 `comparse`/`jobparse` 接口,有重试机制(最多 `maxTryTime` 次)。 **5. 去重判断**:`traverseFolder()` 遍历本地文件目录,判断某个公司或职位是否在 6 个月内(`timeInterval=15552000` 秒)抓过,避免重复抓取。 --- ## 三、子类的核心技术:Playwright + 接口拦截 以猎聘(`spider_liepin.py`)为例,这是最典型的思路: **为什么用 Playwright 而不是直接请求接口?** 因为猎聘有反爬,需要模拟真实浏览器操作。但聪明的地方在于它**并不靠 DOM 解析拿数据**,而是: ```python 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与爬虫总览|00-Python与爬虫总览]] ⬅️ | 01-爬虫架构总览 | ➡️ [[02-爬虫系统建设|爬虫系统建设]]