1. 为什么 Claude Code 写的爬虫总是「跑一次就废」
先说结论:Claude Code 写爬虫的能力没问题,问题出在它拿不到原料。我试过让它抓某电商搜索结果页,十几秒就吐出一个结构干净的文件——requests 拿页面、BeautifulSoup 选节点、随机 sleep、异常重试、User-Agent 轮换、CSV 导出,一应俱全。然后我运行它,返回 403 Access Denied,那串 Reference # 后面跟着 CDN 边缘节点的域名。翻译成人话:请求连目标服务器都没摸到,在 CDN 那一层就被扔了,Claude Code 写的选择器一行都没来得及执行。
这不是模型能力问题,是链路问题。写一个能上生产的采集流程,大概四件事:分析页面结构写选择器、绕过反爬拿到 HTML、处理验证码和 JS 渲染、网站改版后自愈。Agent 唯一擅长的是第一件,而第一件恰好是整条链路里最不值钱的。真正贵的是 IP 池、渲染集群、验证码处理,以及改版之后没完没了的维护。你给再强的模型也一样,它手里没有住宅 IP,没有真实浏览器环境。
所以思路得换:别让 Agent 自己去硬刚基础设施,给它一双能直接调用基础设施的手。这篇要做的就是这件事——在本地settings.json里把 TaoToken 配成统一 Key/API 通道,让 Claude Code 作为 Agent 编排采集任务,自动生成脚本、调用通道、回传结构化数据。适合已经会用 Claude Code 写代码、但被反爬卡在演示阶段的开发者。下面从零跑通一次端到端采集。
2. TaoToken 前置:统一 Key 与 API 通道
TaoToken 在这里的角色是「统一入口」:你不需要在 Claude Code 里散落多个厂商的 Key,也不用为每个模型单独改环境变量。它把模型对话、Coding Plan、API 调用收敛到一套 Key 和一条 API 通道上,Claude Code 通过本地配置指向它,后续 Agent 生成脚本、发起请求、回传数据都走同一条链路。
官网入口:https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
API 基址(不加 UTM):https://taotoken.net/api
你需要提前准备两样东西:一个可用的 API Key,以及确认 Claude Code 已经装好并能正常启动。Key 在控制台的 API Keys 页面创建,创建后只显示一次,复制到本地安全位置。如果你还没建过 Key,直接去这个页面:
https://taotoken.net/console/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
注意:Key 不要写进会提交到 Git 的文件里。下面的
settings.json建议放在用户级配置目录,或者用环境变量注入,别硬编码进项目仓库。
如果你更想先验证模型通道是否通,可以先用模型对话页面发一条消息确认:
https://taotoken.net/model-chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
长期做编码和 Agent 任务的话,Coding Plan 更划算,额度模型和按次调用不一样:
https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
3. 可复制的 settings.json 骨架
Claude Code 读取配置的优先级是:项目级.claude/settings.json> 用户级~/.claude/settings.json。做采集任务我建议用项目级,因为不同项目的采集目标、Collector ID、审批策略都不一样,放项目里好管理。
先建目录和文件:
mkdir -p .claude touch .claude/settings.json然后把下面这份骨架填进去。注意env里的ANTHROPIC_BASE_URL指向 TaoToken 的 API 基址,ANTHROPIC_AUTH_TOKEN用你的 Key。字段名保持原样,不要自己改。
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "sk-你的Key粘贴在这里", "ANTHROPIC_MODEL": "claude-sonnet-4-5", "ANTHROPIC_SMALL_FAST_MODEL": "claude-haiku-4-5" }, "permissions": { "allow": [ "Bash(python:*)", "Bash(pip:*)", "Bash(curl:*)", "Bash(cat:*)", "Bash(ls:*)", "Read(./**)", "Write(./data/**)" ], "deny": [ "Bash(rm -rf:*)", "Bash(git push:*)" ] }, "includeCoAuthoredBy": false }几个字段说明一下。ANTHROPIC_MODEL是主模型,负责生成采集脚本和推理页面结构;ANTHROPIC_SMALL_FAST_MODEL是轻量模型,处理一些快速判断,比如字段映射、格式转换,能省额度。permissions.allow里我放开了python、pip、curl和读写data/目录,因为采集脚本要跑、要装依赖、要落盘。deny里挡掉rm -rf和git push,防止 Agent 误操作。
如果你不想把 Key 写死在文件里,可以改成环境变量引用:
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "${TAOTOKEN_API_KEY}" } }然后在 shell 里export TAOTOKEN_API_KEY=sk-xxx。这样配置文件可以进版本库,Key 留在本地环境。
配置写完后,在项目根目录建一个CLAUDE.md,把采集任务的约束写进去,让 Agent 跨会话记住:
## 数据采集规范 - 所有采集脚本统一放在 scripts/ 目录,输出 JSON 落到 data/ 目录 - 不要自己写 requests + BeautifulSoup 硬抓,先判断目标站是否有反爬 - 采集脚本必须包含:超时设置、重试次数、请求间隔、异常日志 - 输出格式统一为 JSON Lines,每行一个对象,字段名用英文 - 禁止并发超过 3,禁止无间隔连续请求这份CLAUDE.md的作用是跨会话的。下次你新开一个 Claude Code 会话说「更新一下采集脚本」,它会直接按这个规范来,而不是又从零写一个。
4. 端到端验证:让 Agent 生成脚本并回传数据
配置就绪后,跑一次完整的采集验证。目标选一个公开、无反爬的页面,比如某技术博客的列表页,避免一上来就被 403 卡住。
第一步,启动 Claude Code,确认通道通:
claude进去后发一条:
读一下 .claude/settings.json 和 CLAUDE.md,告诉我当前配置的模型和采集规范如果它能正确复述出模型名和采集规范,说明配置生效了。
第二步,让它生成采集脚本。我用一个公开的示例页面做目标:
帮我写一个采集脚本,抓取 https://example.com/blog 的文章列表, 提取每篇文章的标题、链接、发布日期,输出到 data/articles.jsonl。 按 CLAUDE.md 的规范来,包含超时、重试、间隔和异常日志。Claude Code 会生成类似这样的脚本:
import json import time import logging import requests from bs4 import BeautifulSoup from pathlib import Path logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s" ) TARGET = "https://example.com/blog" OUTPUT = Path("data/articles.jsonl") TIMEOUT = 15 RETRIES = 3 INTERVAL = 2.0 HEADERS = { "User-Agent": "Mozilla/5.0 (compatible; DataCollector/1.0)" } def fetch(url): for attempt in range(1, RETRIES + 1): try: resp = requests.get(url, headers=HEADERS, timeout=TIMEOUT) resp.raise_for_status() return resp.text except requests.RequestException as e: logging.warning("attempt %d failed: %s", attempt, e) if attempt == RETRIES: raise time.sleep(INTERVAL * attempt) def parse(html): soup = BeautifulSoup(html, "html.parser") items = [] for node in soup.select("article"): title_el = node.select_one("h2 a") date_el = node.select_one("time") if not title_el: continue items.append({ "title": title_el.get_text(strip=True), "url": title_el.get("href"), "date": date_el.get("datetime") if date_el else None }) return items def main(): OUTPUT.parent.mkdir(parents=True, exist_ok=True) html = fetch(TARGET) items = parse(html) with OUTPUT.open("w", encoding="utf-8") as f: for item in items: f.write(json.dumps(item, ensure_ascii=False) + "\n") logging.info("wrote %d items to %s", len(items), OUTPUT) if __name__ == "__main__": main()第三步,让它自己跑:
运行这个脚本,把结果前 3 行打印出来Claude Code 会执行python scripts/collect.py,然后head -3 data/articles.jsonl。如果输出类似:
{"title": "第一篇文章", "url": "/blog/1", "date": "2026-01-15"} {"title": "第二篇文章", "url": "/blog/2", "date": "2026-01-12"} {"title": "第三篇文章", "url": "/blog/3", "date": "2026-01-10"}说明端到端链路通了:Claude Code 通过 TaoToken 通道生成脚本、执行脚本、回传结构化数据。这一步是整个流程的地基,地基通了,后面接反爬能力才有意义。
5. 本篇常见错排查
报错一:401 Unauthorized或invalid api key
先检查settings.json里的ANTHROPIC_AUTH_TOKEN有没有多余空格,Key 是不是复制完整。然后确认ANTHROPIC_BASE_URL是https://taotoken.net/api,结尾不要多加斜杠。如果用的是环境变量引用,确认 shell 里echo $TAOTOKEN_API_KEY有值,且启动 Claude Code 的终端和 export 的终端是同一个。
报错二:model not found或模型名不识别
ANTHROPIC_MODEL填的模型名要和通道支持的名称一致。如果你不确定有哪些可用模型,先去模型对话页面发一条消息,看它默认用的是什么模型,把那个名字填进来。别自己拼一个不存在的版本号。
报错三:脚本能生成但运行报ModuleNotFoundError
Claude Code 生成的脚本依赖requests和beautifulsoup4,但你的环境没装。让它自己装:
pip install requests beautifulsoup4或者在CLAUDE.md里加一条「运行前先检查依赖,缺什么装什么」,让它自动处理。
报错四:采集目标返回 403,脚本一行没执行
这就是开头说的反爬问题。Claude Code 写的选择器没问题,但请求在 CDN 层就被拦了。这时候不要让它反复改选择器,那是白费力气。正确做法是换一条能拿到 HTML 的通道,或者把目标换成无反爬的页面先跑通流程。判断方法很简单:用curl -A "python-requests/2.31.0" -o /dev/null -w "%{http_code}" 测一下,如果返回 403,就是通道问题,不是代码问题。
报错五:settings.json改了但没生效
Claude Code 只在启动时读配置。改完settings.json要退出重进。另外确认文件路径对:项目级是.claude/settings.json,用户级是~/.claude/settings.json,别放错地方。JSON 格式也要检查,多一个逗号都会导致整个文件被忽略。
报错六:Agent 每次会话都重新写一遍脚本
这是没把约束写进CLAUDE.md的后果。把采集规范、脚本路径、输出格式写进去,它下次就会复用而不是重写。如果已经有现成的脚本,直接在CLAUDE.md里写「采集脚本已存在于 scripts/collect.py,不要新建,需要修改时直接改这个文件」。
6. 把能力固定下来:从演示到生产
跑通一次不算完,关键是让这套流程跨会话活下来。三个动作。
第一,把采集脚本和CLAUDE.md一起提交到项目仓库。脚本是资产,规范是约束,两者缺一不可。下次任何人(包括 Agent)打开这个项目,都知道采集该怎么做。
第二,如果目标站有反爬,不要硬刚。先判断拦截类型,再决定是换通道还是换目标。判断命令:
curl -s -o /tmp/body.html -w "%{http_code}" \ -A "python-requests/2.31.0" --max-time 20 \ "https://目标站/路径" grep -io "[^<]*" /tmp/body.html | head -1返回 403 且标题是 Access Denied 之类的,就是通道问题。这时候让 Claude Code 去改选择器没有任何意义。
第三,长期做编码和 Agent 任务的话,把额度模型换成 Coding Plan,比按次调用省。入口:
https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
如果你在接入过程中遇到配置报错、Key 不生效、模型名不识别这类问题,先去 API Keys 页面确认 Key 状态,再对照接入文档检查字段:
https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
Claude Code 相关的接入细节,包括settings.json字段说明和常见问题,文档里有完整对照表:
https://taotoken.net/claude-code-anthropic?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content=
最后说一个我踩过的坑:一开始我把 Key 硬编码进settings.json然后提交了,后来换 Key 的时候满仓库找。现在改成环境变量引用,配置文件进版本库,Key 留在本地,换 Key 只改一个环境变量,不用动任何文件。这个习惯建议你一开始就养成。