×

自建爬虫 vs 官方 API:成本、稳定性、风险一次算清(附 Python 源码)

万邦科技Lex 万邦科技Lex 发表于2026-10-27 16:35:55 浏览35 评论0

抢沙发发表评论

# 自建爬虫 vs 官方 API:成本、稳定性、风险一次算清(附 Python 源码)

每个做电商数据的团队都纠结过这个问题:接官方 API 要走审核、要等权限,看着就麻烦;自己写个爬虫,两周就能出数据,还不要钱。

这篇把这笔账彻底算清。先说结论:

**爬虫不是"省钱的方案",是把成本换了个形式——从"花钱"变成"花人 + 担风险"。** 算完三年总账,爬虫通常是官方 API 的 2~4 倍,而最大的一项成本是"养一个懂爬虫的人"。

但我也不会一边倒。爬虫有它合理的场景,第四节专门讲哪些情况该爬。先把账摆出来,你自己判断。

---

## 一、成本:把"看起来免费"的东西标上价

爬虫最大的迷惑性在于:**它的成本几乎全部是隐性的**。没有账单,没有报价单,全部体现在"某个人每个月花在它身上的时间"里。

逐项拆开:

**① 首次开发**。大多数团队的预估是"一周",实际是 2~4 周。因为真正花时间的不是写解析器(那确实只要两天),是处理长尾:懒加载、翻页截断、字段在不同商品页上的十几种变体。

**② 持续维护**。这是大头,也是最容易被漏算的。页面会改版——改成版式、改类目页结构、加一层前端渲染,平均每月 1~~2 次,每次修复 0.5~~2 天。算下来,**养一个爬虫需要 0.2~0.4 个人力,常年不停**。

**③ 反爬对抗的设备成本**。IP 代理池、请求频率控制、失败重试——合法合规的部分同样有真金白银的月费。

**④ 人的风险**。爬虫系统往往只存在于一个人的脑子里。这个人休假、离职,系统跟着停摆——而你甚至不知道它哪天停的(下一节讲这个)。

**官方 API 的成本**则几乎全部是显性的:接入人力(1~3 周,含等审核的并行期)、持续维护(平台接口变更频率远低于页面改版,且有公告期)、调用费用。

同一个需求(三平台商品 + 订单同步),我们按一名中级后端的全成本 3.5 万/月算三年账:

| 成本项       | 自建爬虫                       | 官方 API                 |
| --------- | -------------------------- | ---------------------- |
| 首次开发 / 接入 | 2.6 万(3 周)                 | 3.5 万(1 人月,含审核并行期)     |
| 持续维护      | **31.5 万**(0.25 人力 × 36 月) | 10.1 万(0.08 人力 × 36 月) |
| 代理 / 调用费  | 2.9 万(代理池月费)               | 3.6 万(调用与服务费)          |
| **三年合计**  | **≈ 37 万**                 | **≈ 17.2 万**           |

差距主要来自②:**API 的"维护"是读公告和改字段名,爬虫的"维护"是重新理解一个被改过的页面**。前者有文档,后者只有你的猜想。

这张账能算,是因为它有模型。下面的计算器你可以拿去代入自己的数字:

```python
# tco.py —— 三年总拥有成本计算器
# 参数按你们自己的实际情况改,模型不变
from dataclasses import dataclass


@dataclass
class Team:
    """团队参数"""
    salary_month: float = 35000      # 一名相关岗位的全成本/月(工资 × 1.4 起步)


@dataclass
class CrawlerPlan:
    """爬虫方案:大部分成本是隐性的,所以要显式建模"""
    build_weeks: float = 3.0         # 首次开发(现实值 2~4 周,别用 1 周)
    maintain_fte: float = 0.25       # 常年维护人力占比(0.2~0.4,低于 0.2 通常意味着没人在管)
    proxy_month: float = 800         # 代理与设备月费
    months: int = 36

    def cost(self, t: Team) -> dict:
        # 按周折算:每月 21.75 个工作日,每周 5 天
        build = t.salary_month / 21.75 * 5 * self.build_weeks
        maintain = t.salary_month * self.maintain_fte * self.months / 12
        infra = self.proxy_month * self.months
        return {"首次开发": round(build, 1),
                "持续维护": round(maintain, 1),
                "代理与设备": round(infra, 1),
                "合计": round(build + maintain + infra, 1)}

# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
@dataclass
class ApiPlan:
    """官方 API:成本几乎全部显性"""
    build_months: float = 1.0        # 含与审核期并行的开发
    maintain_fte: float = 0.08       # 读公告、改字段名、处理限流
    api_month: float = 1000          # 调用费 + 软件服务费
    months: int = 36

    def cost(self, t: Team) -> dict:
        build = t.salary_month * self.build_months
        maintain = t.salary_month * self.maintain_fte * self.months / 12
        fees = self.api_month * self.months
        return {"首次接入": round(build, 1),
                "持续维护": round(maintain, 1),
                "调用与服务费": round(fees, 1),
                "合计": round(build + maintain + fees, 1)}


if __name__ == "__main__":
    t = Team()
    c = CrawlerPlan().cost(t)
    a = ApiPlan().cost(t)
    w = max(len(k) for k in c)
    for k in c:
        print(f"{k:<{w}}  爬虫 {c[k]:>8} 万    API {a[k]:>8} 万")
    print(f"\n倍数:{c['合计'] / a['合计']:.1f}x")
```

跑出来就是上面那张表。**你团队的实际数字可能不同,但倍数关系通常落在 2~4 倍**——因为决定倍数的是"页面改版频率 ÷ 接口变更频率",这个比值对任何平台都在 10 倍以上。

> 有一种情况会让这个计算器失真:你只爬**一个**页面、只用**三个月**。那爬虫确实便宜。计算器的隐含前提是"长期、多页面、商用"——这也是大多数人纠结这个问题的真实场景。

---

## 二、稳定性:不是"能不能跑",是"断了你知不知道"

这是两种方案差距最大、又最少被认真比较的维度。

### 爬虫的故障模式:静默失败

爬虫最危险的特性是**它的失败经常不报错**。

页面改版后,CSS 选择器取到的价格字段是空的——但程序不崩溃,只是默默写进去一行空数据。三天后财务发现报表价格对不上,往前追,发现已经空了三天。

第 9 篇讲过一句话:**返回可解释的结果,比返回正确数据更重要**。爬虫恰恰相反:它给不出可解释的结果,页面改版后它连"我现在是坏的"都不告诉你。

另一个爬虫特有的问题是**数据可信度**。你爬到的是"页面展示价"——但页面展示价不一定是成交价:会员价、叠加优惠券、区域差异、千人千面的推荐价。商品价格同步这种场景,展示价和 API 返回的实际价格能差出 5%~15%,而这个差异你很难系统性发现。

### API 的故障模式:有状态、可归因

API 也会挂——平台故障、限流、字段弃用。区别在于:

|        | 爬虫                | 官方 API           |
| ------ | ----------------- | ---------------- |
| 失败形态   | 静默,返回空或错数据        | 报错,有错误码          |
| 能否定位原因 | 靠猜(页面又改了?IP 被封了?) | 错误码直接告诉你         |
| 恢复     | 人工修解析器,小时~天级      | 限流自动恢复 / 平台公告修字段 |
| 可监控性   | 极难(没有"正常"的基准)     | 成功率、错误码分布都是现成指标  |

### 共同的必修课:数据校验

不管数据从哪来,校验都得做。这段代码对两种来源都适用——尤其是对爬虫,它是你发现"静默失败"的唯一手段:

```python
# integrity.py —— 数据完整性与静默失败检测
# 对 API 和爬虫的数据一视同仁地校验
from dataclasses import dataclass


@dataclass
class Issue:
    item_id: str
    field: str
    kind: str      # missing / out_of_range / mismatch
    detail: str

# 封装好API供应商demo url=https://console.open.onebound.cn/console/?i=Lex
REQUIRED = ("item_id", "title", "price", "stock")
PRICE_RANGE = (0.01, 10_000_000)


def validate(items: list[dict], source: str) -> list[Issue]:
    """单源校验:字段缺失 + 数值越界"""
    issues = []
    for it in items:
        iid = str(it.get("item_id", "?"))

        for f in REQUIRED:
            v = it.get(f)
            if v is None or v == "":
                # 爬虫静默失败最典型的形态:字段存在但为空
                issues.append(Issue(iid, f, "missing", f"{source} 返回空"))

        p = it.get("price")
        if isinstance(p, (int, float)) and not (PRICE_RANGE[0] <= p <= PRICE_RANGE[1]):
            issues.append(Issue(iid, "price", "out_of_range", f"{source} 价格 {p}"))

    return issues


def cross_check(primary: list[dict], secondary: list[dict],
                tol: float = 0.01) -> list[Issue]:
    """
    双源比对:比如 API 数据 vs 3 天前的快照。
    同一商品价格波动超过 tol(1%),要么真降价了,要么有一边坏了。
    配合告警,这是抓"静默失败"最有效的一招——
    因为静默失败不会自己报警,只有比对能暴露它。
    """
    ref = {str(x["item_id"]): x for x in secondary}
    issues = []
    for it in primary:
        iid = str(it["item_id"])
        old = ref.get(iid)
        if not old:
            continue
        p_new, p_old = it.get("price"), old.get("price")
        if p_new is None or p_old in (None, 0):
            continue
        if abs(p_new - p_old) / p_old > tol:
            issues.append(Issue(
                iid, "price", "mismatch",
                f"{p_old} -> {p_new}(变动 {abs(p_new - p_old) / p_old:.1%})",
            ))
    return issues
```

`cross_check` 是我们生产环境里跑了很多年的一个函数。它不关心数据从哪来,只关心**数据是不是还讲得通**。爬虫团队尤其需要它——因为没有它,你可能三个月都不知道自己的解析器坏了。

---

## 三、风险:这一项没有"权衡",只有红线

前两项是算术题,这一项是规则题。

把话说在前面:**我不会在这篇文章里讨论任何"绕过反爬"的技术**。不是因为怕事,是因为在国内的法律环境下,那已经不是技术选型的问题了。

### 商用场景下,爬虫面临三层风险,一层比一层重

**第一层:民事(反不正当竞争)**

绕开平台的访问控制抓数据、违反 robots 协议或用户协议抓取,在司法实践中普遍被认定为不正当竞争。这类判例非常多(大众点评诉百度、淘宝诉美景等都是公开判例),判赔金额从几十万到数千万不等。

**第二层:刑事**

这一层很多人不知道,但它真实存在:**如果抓取涉及突破或规避技术保护措施**(破解加密参数、伪造签名、打码平台过验证码),可能触及《刑法》第 285 条"非法获取计算机信息系统数据罪"——这是**刑事**罪名,有真实获刑判例,个人刑期、单位罚金都有。

爬取的内容一旦涉及**用户个人信息**(买家昵称、地址、手机号),还叠加《个人信息保护法》,责任更重。

**第三层:业务连续性**

就算前两层都侥幸没发生,平台识别到爬虫行为后封 IP、封账号、法律函三连——你的数据管道说断就断,而你的业务是建立在这条管道上的。**用爬虫做商用数据源,等于把业务的命脉押在一个随时可能被合法切断的东西上。**

### 两个常见误区,顺手拆掉

**"大厂也在爬"** —— 大厂爬大厂,是法务团队规模相当的对抗,输了一起谈,赔得起也耗得起。小团队没有这个筹码,同样的行为,风险完全不对等。

**"我只是自用,不商用"** —— 自用研究的风险确实低得多(这是真的,第四节也会说爬虫的合理场景)。但"自用"和"自用着自用着就给客户看了"之间的距离,通常只有一个业务增长周期。**数据一旦进入商业流程,就回不去了。**

### API 的风险也要诚实列出来

API 不是零风险:接口会下线、类目会调整、政策会变。但关键区别是——**平台对这些变更有公告期**(通常 30~90 天),你可以提前改代码;而页面改版不会通知你。另外,用 API 也有合规要求(超范围使用数据同样会被封),这条红线两边都存在。

所以风险这一项的结论是:**商用场景下它是一票否决项,不是加权项。**

---

## 四、什么时候爬虫是合理选择

说完了不合理的,得把合理的说清楚,不然这篇就成了立场文。

**爬虫合理的场景:**

1. **数据在官方 API 里根本不存在**。全网竞品价格监控、搜索引擎数据、社媒舆情——这些没有"官方 API"可接,公开信息抓取 + 合规使用是正当的。
2. **一次性研究 / 学习**。跑一次分析、写一篇报告、验证一个想法,不进入业务流程、不对外提供。这个场景爬虫完全成立。
3. **平台没有开放能力的长尾站点**。有些小平台根本没有开放平台,无 API 可接。
4. **你自己店铺的展示层信息**。详情页装修、页面呈现效果这类"展示层"数据,API 里没有,爬自家页面没有争议。

**不合理的场景只有一个,但最常见**:拿爬虫当 API 的"免费替代"去商用——尤其是数据明明在 API 里有的情况。这不是技术选型,是**把风险转移给三个月后的自己**。

一个快速自查清单,五个问题:

1. 这份数据官方 API 里有没有?(有 → API)
2. 用途会不会进入商业流程?(会 → API)
3. 有没有人能长期养它?(没有 → API)
4. 数据错了的代价是什么?(影响客户/财务 → API)
5. 需要多高的更新频率?(高频 → API,因为高频爬取必然撞上对抗)

**五个问题里有两个以上答案是括号里的那个,这个决策就已经做完了。** 真正还能选爬虫的,是五个问题都指向另一边的场景——那种场景其实不多,但确实存在。

---

## 五、最后

这篇的立场我尽量放平了:爬虫不是原罪,它有它的场景;API 也不是圣杯,它有自己的成本和维护量。

但有一个区别必须说透:**API 花的钱买的是"确定性"**——确定性的数据口径、确定性的错误反馈、确定性的法律边界。爬虫省下的钱,本质是从这三个确定性里借的,利息在后面。

我们做三平台数据接口服务,这篇里的账就是我们自己算过的账——也是我们客户 switching(从爬虫迁到 API)时反复验证的账。`tco.py` 的参数改成你们团队的真实数字,跑一遍,比看任何人的结论都有用。

下一篇写「多店铺授权管理」:token 的存储与加密、并发刷新撞车、单店授权过期的隔离——那是接入体系的最后一个坑区。

---

*附:`tco.py` 里 `maintain_fte=0.25` 是我们从数十个爬虫系统的维护投入里归纳的经验区间(0.2~0.4)的中位值。如果你的爬虫由多人共管,实际投入可能更高——共管意味着责任分散,这是另一个隐性成本。*


群贤毕至

访客