基于 LangGraph 的单体 ReAct Agent 爬虫代码生成框架:
- Single ReAct Agent:理解用户需求 -> 抓取与缓存 -> 字段映射(JSONPath/XPath)→ 生成可运行的 Python 爬虫代码 ->(可选)执行与验证产出文件
相关设计见:docs/architecture.md
更多文档见:
docs/TECH_STACK.md:技术栈说明docs/AGENT_TOOLS.md:工具能力说明
推荐使用 uv:
uv sync --all-extras或使用 pip(开发环境建议带 dev 依赖):
pip install -e ".[dev]"安装 Playwright 浏览器:
python -m playwright install项目会读取 .env 与环境变量(见 src/config.py)。支持多种 LLM provider(openai / anthropic / google / litellm),通过 LLM_DEFAULT_PROVIDER 选择。最少需要:
LLM_DEFAULT_PROVIDER(可选;默认openai)OPENAI_API_KEY(使用 openai provider 时必填)OPENAI_BASE_URL(可选;默认https://open.bigmodel.cn/api/paas/v4/)LLM_DEFAULT_MODEL(可选;默认glm-4.6)
多模态视觉模型可独立配置:
LLM_VISION_PROVIDER(可选;视觉模型 provider,未设置时回退到LLM_DEFAULT_PROVIDER)LLM_VISION_MODEL(可选;视觉模型名称,未设置时回退到LLM_DEFAULT_MODEL)LLM_VISION_API_KEY(可选;视觉模型专用密钥,未设置时回退到 provider 默认密钥)LLM_VISION_BASE_URL(可选;视觉模型专用基础 URL,未设置时回退到 provider 默认地址)
如果希望”普通模型”和”多模态模型”分开配置(例如多模态走 DeepSeek),可在 .env 中添加:
LLM_VISION_API_KEY=<your-deepseek-key>
LLM_VISION_BASE_URL=https://api.deepseek.com
LLM_VISION_MODEL=deepseek-chat默认进入交互式模式:
crawler-agent单次任务模式(需同时提供 --url、--fields、--notes):
crawler-agent --url "https://example.com" --fields "title,price" --notes "商品列表"交互模式内置会话命令:
- 输入
/new:创建并切换到新会话(新的thread_id与独立缓存) - 输入
quit/exit/q:退出交互模式
其它命令:
crawler-agent versionAgent 会优先走“快路径”再深入定位:
capture_page:加载页面并捕获网络流量(自动尝试滚动触发懒加载),返回候选cache_keysread_cached_content:快速查看缓存正文文本,判断页面是否包含目标线索search_in_cache_text:在指定cache_key内检索缓存线索(HTML 会搜索文本节点与常见属性值并返回命中元素的 XPath;JSON 会搜索文本值,必要时可同时搜索键名)- HTML 适合搜索可见文本、
href、src、class、id、data-*、aria-*等线索 - JSON 建议先用
include_keys=True搜 key 名(数值字段尤其有效) - 多处命中时看每条命中的
context与exact_path
- HTML 适合搜索可见文本、
inspect_matches_in_cache:当多个match_id都像目标字段时,读取它们的父/子/同级局部结构,帮助 Agent 做消歧- 适合区分“同样叫 price/title 的多个节点,到底哪一个属于目标列表项”
- 也适合在属性命中后查看该 XPath 周围的列表容器与字段结构
map_path_in_cache:基于match_id生成路径映射- 返回
exact_path+group_path/group_hits/sibling_samples,便于处理列表字段 - 对 JSON 而言,
group_hits表示group_path命中的节点数;sibling_samples预览这些匹配节点的值形态 match_id仅在“当前缓存会话”内有效;切换会话(如/new)后需重新搜索生成新的match_id
- 返回
extract_from_cache:对候选路径做样例验证- JSON 分支直接使用
jsonpath-ng执行表达式,工具侧与生成代码侧语义一致 values保持原生匹配顺序,不再自动拍平末端列表;例如$.items[*].tags会返回[["a", "b"], ["c"]]
- JSON 分支直接使用
- 页面结构不清晰时:先
capture_page(url)(会缓存screenshot:{url}),再analyze_page_with_vision(url, question=...)(布局/区域/按钮定位)
- 运行时通过
CrawlerContext(src/agent/crawler_context.py)注入 LangGraph Runtime。每次运行构造不可变的CrawlerContext实例,通过 LangGraph Runtime 传递给所有节点和工具。 - 展示事件由
RuntimeDisplayEventSink(src/services/runtime_events.py)Protocol 定义,CLI 层通过CLIRuntimeDisplaySink实现流式输出。
- 缓存实现为内存缓存(见
src/services/cache.py),按会话隔离(thread_id/session_id)。 search_in_cache_text生成的match_id绑定当前会话;map_path_in_cache会校验会话与cache_key,防止跨会话误用。- CLI 输出默认使用纯文本提示(无 emoji 图标),兼容 Windows GBK 控制台。
- 文档与代码不一致时,请以代码为准(单体 Agent 入口见
src/agent/__init__.py;运行时上下文见src/agent/crawler_context.py)。
从本次版本开始,CLI 每次执行单个任务都会在当前终端工作目录下自动创建:
./crawler-agent-runs/<thread_id>/
其中:
raw/:机器友好、按需追加写入的原始记录与产物readable/:面向人审计的整理输出(例如call_record.md)
raw/ 下会实时写入以下内容,便于观察和监控任务执行过程:
raw/events.jsonl:全流程事件流(run_start/run_end/cache_write/llm_start/llm_end/tool_start/tool_end/shell_confirm/exception)raw/meta.json:本次运行元信息(耗时、会话 ID、配置快照等)raw/state/stream.jsonl:标准化运行流式 envelope(主运行轨迹)raw/state/final_state.json:任务结束时的最终状态raw/cache/:中间缓存产物(html/json/content/screenshot)与raw/cache/index.jsonraw/llm/:LLM 调用输入输出(请求与响应)raw/tools/:工具调用输入输出
说明:
- 功能默认开启,不自动清理历史目录。
settings_snapshot默认不会写入litellm_api_key。- 当前模式为完整记录(Full),会包含网页内容和 AI 输入输出,请按需做好本地目录权限与数据管理。