如何设计一个可配置易维护的爬虫系统

谷德IP代理 2026-05-09 10:43:58

去年双十一之前,我想自己做一个电商比价小工具。随手写了个爬虫,刚跑三分钟,直接翻车——IP被网站封了。

更尴尬的是,半个月后我想换个站点接着爬,回头翻当初那堆代码,瞬间头大:请求地址全写死在代码里,页面解析逻辑塞在循环里面,代理配置更是东一块西一块,散落在五个函数当中。

想改?看了一圈还不如直接推倒重写。

这就是典型的“能跑就行”写法埋下的坑。今天就跟大家好好聊聊,怎么搭一套可配置、好维护的爬虫架构,顺便把代理IP该怎么规范用,一次性讲透。

如何设计一个可配置易维护的爬虫系统

先改掉把参数写死的坏习惯


刚入门写爬虫的朋友基本都有个通病:网站链接写死在代码、页面筛选器写死、就连请求头都直接硬编码。


response = requests.get('https://example.com/products/123')
title = response.xpath('//h1/text()').get()


平时简单爬两页没问题,可一旦要批量爬上千个商品,或是换个新网站,立马就难受了。

最简单的解决办法:把所有会变动的内容抽出来,统一放到配置文件里管理

给大家看一段精简的YAML配置示例:


targets:
  - name: "商品信息"
    url: "https://example.com/products/{product_id}"
    method: "GET"
    headers:
      User-Agent: "Mozilla/5.0 ..."
    fields:
      title: "//h1/text()"
      price: "//span[@class='price']/text()"


爬虫只负责读取配置、发起请求、按照规则解析数据。换站点?改配置就行。要新增抓取字段?也只改配置就行,核心代码完全不用动。

这就是可配置设计的精髓:把要做什么,和具体怎么做彻底分开

代理IP怎么优雅接入,不乱代码


做爬虫被封IP,早晚都会遇到。代理IP说白了,就是给咱们不停换马甲隐藏身份。

但很多人用代理都是瞎写一通,到处插代码,时间一长整个项目乱成一锅粥。

正确思路很简单:单独封装一个代理管理器,它只干一件事——对外提供可用代理IP。


class ProxyManager:
    def get_proxy(self):
        # 从代理池取出一个IP
        # 提前检测IP是否有效
        # 失效自动剔除、切换新IP
        return proxy


爬虫每次发请求前,直接调用 get_proxy() 拿IP就够了。至于代理是付费接口获取、本地文件读取,还是自己爬的免费代理列表,全都封装在管理器内部,爬虫业务完全不用关心。

还能再进阶一步,把代理相关设置也写进配置:


proxy:
  enabled: true
  source: "http://api.proxy-service.com/get?key=xxx"
  fallback_proxies: ["ip1:port", "ip2:port"]
  retry_on_fail: 3


后续想换代理服务商、调整备用IP,只改配置文件,不用碰一行业务代码。

好维护的核心:单一职责,各司其职


很多爬虫项目最后变成没人敢碰的烂摊子,不是业务逻辑有多复杂,而是一个函数包揽所有活:既要发请求、又要解析页面,还要处理反爬、顺带打印日志。

一定要拆分拆解。

一套规范好维护的爬虫,至少要拆成五大模块:

  • 请求器:只负责发网络请求,处理代理和请求重试
  • 解析器:只按配置规则,提取页面需要的数据
  • 调度器:管控URL抓取顺序,控制爬取频率
  • 代理管理器:全权负责IP池获取、校验、自动切换
  • 数据处理器:做数据清洗、去重、入库存储

每个模块都是独立黑盒,改请求逻辑不影响解析,换代理接口不用动调度器。低耦合的好处就是:改一处不牵连全局,新人接手看一眼架构,半小时就能看懂整体逻辑。

爬虫正式上线,别上来就暴力多线程


代码写完别急着开上百个线程硬刚网站,先想清楚几个实际问题:

  • 请求失败该重试几次?失败后用原IP重试,还是直接换IP?
  • 遇到429请求过多限制,系统该怎么自动应对?
  • 代理全部失效时,有没有备用兜底方案?

把这些异常容错逻辑,全部写到配置里:


retry:
  max_attempts: 3
  backoff_factor: 2  # 指数退避:间隔2秒、4秒、8秒递增
  change_proxy_on_fail: true

rate_limit:
  requests_per_second: 2
  burst: 5

failure_handling:
  on_status_429: "switch_proxy_and_retry"
  on_timeout: "retry_same_proxy"


千万别把重试、限流、异常策略硬写在代码里。不同网站反爬严格程度不一样,配置随时可调,写死在代码里每次修改都要重新部署,特别麻烦。

总结


想搭一套稳定好维护的爬虫系统,记住三句核心就行:

  1. 所有会频繁变动的内容,全部抽离放进配置文件,包括链接、解析规则、代理源、重试策略;
  2. 单独封装代理管理器,把IP相关逻辑隔离,业务爬虫只管用IP,不用管IP来源;
  3. 按职责拆分各个模块,请求、解析、调度、代理、存储互不干扰。

当初IP被封后,我花了三天彻底重构整套爬虫。后面再换目标站点,改下配置十几分钟就能直接跑数据;代理服务商涨价或换接口,改个配置地址就搞定。

这种随心所欲、一切尽在掌控的感觉,才是写爬虫最舒服的状态。