尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

LangChain + Playwright:从零构建能搜索网页的 Web Agent

LangChain + Playwright:从零构建能搜索网页的 Web Agent 你会不会觉得现在的 Agent 只会聊天不会“干活”最近两年 Agent 概念被反复讨论市面上也出现了大量 Demo让它写一首诗、画一张图、整理一份周报看起来都很聪明。但一旦遇到真实业务问题——比如“去搜索引擎查一下 LangChain Agent 的近期教程汇总前三条结果的标题和网址”很多 Agent 就露馅了。它能给出一个看似合理的回答但里面的链接可能是编的信息可能是过时的它根本没有真正“打开浏览器去看过”。这不是模型能力的问题而是缺少一个能操作真实网页的执行层。如果用一句话概括本文要做的智能体LangChain 负责“大脑”Playwright 负责“手脚”。LangChain 负责规划任务、选择工具、解析结果Playwright 负责打开浏览器、搜索关键词、点击按钮、读取页面内容。两者组合之后Agent 才真正从“会聊天”变成“能办事”。这篇文章会从零搭一个最小可运行的 Web Agent包含完整代码和运行验证。读完你能理解 Agent 工具调用的核心流程能动手跑通一个真实的网页信息收集任务也知道在工程落地时容易踩哪些坑。1. 为什么是 LangChain Playwright它真正解决了什么问题在解释技术细节之前先聊一个更根本的问题为什么要这样组合单独用 LangChain 或单独用 Playwright 不行吗先说结论单用 LangChain 可以做 Agent 规划但 Agent 没有“眼睛”和“手”单用 Playwright 可以自动化浏览器但脚本是死的只能按你写死的步骤执行。真正有价值的地方是把两者接起来。过去解决“网页信息获取”类需求通常有几个方案RAG 文档检索把网页内容下载后切片、向量化再让模型基于检索结果回答。问题是它只能事后检索无法应对需要登录、点击、翻页的动态场景。手写爬虫脚本用 requests 或 Scrapy 实现固定逻辑。问题是页面结构一变代码就要跟着改维护成本极高。Playwright 自动化脚本能模拟真实用户操作浏览器但每一步都是硬编码的缺少根据结果动态调整下一步的能力。这几种方案的核心缺陷是一致的缺少“根据目标自主决定下一步做什么”的能力。LangChain Playwright 的组合改变的是执行链路。用户用自然语言提出目标Agent 自动规划出“搜索→打开链接→读取正文→汇总结果”的步骤并在每一步观察工具返回结果判断是否继续。如果打开网页后发现内容不符合预期它可以换一个关键词重新搜索而不是傻傻地继续执行。从应用场景看这个组合适合以下几类人正在做 Agent 开发希望让 Agent 具备真实网页交互能力的开发者做测试开发想用自然语言描述测试场景由 Agent 驱动浏览器完成操作和断言需要定期做网页信息收集、内部系统巡检、报表生成的工程师想理解 LangChain Agent 工具调用原理为后续学习 LangGraph、MCP 打基础的学习者。它不适合做什么不适合高并发爬虫也不适合纯离线的数据处理。Playwright 本质是真实浏览器性能和稳定性与无头浏览器资源直接相关。把它当成一个“能对话的浏览器操作助手”而不是“抓数据服务器”定位就对了。2. LangChain 和 Playwright 的核心概念与分工2.1 LangChainLLM 应用开发框架LangChain 是一套用于开发大语言模型应用的开源框架核心价值是把模型调用、提示词管理、工具注册、Agent 循环这些重复劳动抽象出来。你不需要自己写一个复杂的事件循环去调用模型、拼接上下文、解析工具结果LangChain 提供了现成组件。在 Agent 场景里LangChain 提供两个关键能力Agent 执行器AgentExecutor维护“模型思考→选择工具→执行工具→返回观察结果→再思考”的循环。工具抽象允许你把自己的 Python 函数注册成工具并附带描述信息让模型知道这个工具是干什么的、参数怎么传。2.2 Agent 与 ReAct 范式Agent 并不是一个神秘的东西。它的核心是让大模型在循环中做决策根据用户任务和当前已经获得的信息决定调用哪个工具、传什么参数然后观察工具返回值再决定下一步。ReAct 是其中最经典的一种范式全称是 Reason Act。模型按固定格式输出Thought: 我应该先搜索关键词 Action: search_bing Action Input: {query: LangChain Agent 教程}系统执行 Action 对应的工具函数把结果作为 Observation 返回给模型。模型看到 Observation 后继续输出 Thought、Action……直到得到最终答案输出 Final Answer。这套机制听起来简单但它是 Agent 真正的“规划引擎”。LangChain 的create_react_agent底层就是把模型的思考格式、工具描述、历史观察拼接成一次完整的 Prompt然后循环执行。2.3 Playwright真实浏览器操作框架Playwright 是微软开源的浏览器自动化框架支持 Chromium、Firefox、WebKit。相比 SeleniumPlaywright 有几个实用优势维度PlaywrightSelenium浏览器驱动内置下载无需单独安装 driver需要单独下载对应 driver等待机制支持自动等待和显式等待偏手写显式等待定位 API支持get_by_role、get_by_text等语义化定位经典 WebDriver API调试工具支持 Trace、Codegen、UI Mode工具链成熟但相对分散API 风格同步/异步 API 都简洁经典 WebDriver 风格Playwright 在 Agent 中的角色可以理解为“执行手脚”。无论是打开网页、填写表单、点击按钮、读取页面文本还是截图、录屏、保存请求信息它都能做。2.4 LangChain 与 LangGraph 的区别很多初学者会混淆 LangChain、LangGraph 和 Agent 的关系。这里给一个简单判断LangChain 是 LLM 应用开发框架提供模型、Prompt、Tool、Agent 等基础组件LangGraph 是一个基于图状态机的编排框架可以显式控制节点和边的执行逻辑create_react_agent是 LangChain 提供的一种开箱即用的 Agent 封装适合快速搭建LangGraph 则更适合复杂流程比如需要分支、循环、人工审批、状态持久化的场景。维度LangChain AgentLangGraph控制方式高层封装开箱即用显式状态机灵活控制适用场景快速搭 Agent、跑通 Demo复杂流程、分支、人工确认学习成本低中等是否互斥不是不是本文先用create_react_agent做最小闭环最后一章再聊什么时候应该切换到 LangGraph。3. 架构设计一个可运行的 Agent 需要哪些零件动手写代码之前先把零件理清楚。一个具备网页操作能力的 LangChain Agent核心由四部分组成。第一大模型LLM。它负责理解任务、生成行动计划、解析工具结果。本文示例使用 OpenAI 兼容接口你可以换成任何兼容 OpenAI 协议的服务也可以换成本地模型。第二工具集合Tools。每个工具是一个 Python 函数LangChain 会读取函数名和 docstring 生成给模型看的工具描述。工具需要满足“单输入单输出、返回结果尽量结构化”的要求。第三Agent 循环。由 LangChain 的 AgentExecutor 完成负责把模型输出转化成工具调用并把结果返回给模型继续推理。第四浏览器执行层。由 Playwright 提供工具的内部实现会启动无头浏览器、执行页面操作、提取文本内容然后返回给 Agent。整体执行流程如下用户输入任务 ↓ LLM 规划搜索关键词“LangChain Agent 教程” ↓ 工具 search_bing 调用 Playwright 打开必应并搜索 ↓ 返回搜索结果文本 ↓ LLM 看到结果觉得需要提取前三条链接的正文 ↓ 工具 open_and_extract 打开对应网页并提取正文 ↓ LLM 汇总结果输出 Final Answer理解这个流程后你会发现工具描述非常关键。模型只能通过函数名和 docstring 判断“这个工具能干什么、参数怎么传”所以工具描述要写得像一份清晰的 API 文档而不是写给同事看的注释。4. 环境准备与安装本文示例使用 Python 3操作系统不限但命令在 Windows 和 Linux 上略有差异。4.1 创建虚拟环境推荐使用虚拟环境隔离依赖避免污染系统 Python。python -m venv .venv激活虚拟环境# Windows (CMD) .venv\Scripts\activate # Windows (PowerShell) .venv\Scripts\Activate.ps1 # macOS / Linux source .venv/bin/activate激活后命令行提示符前会出现.venv标识。4.2 安装依赖本文需要安装的依赖如下langchain langchain-openai playwright python-dotenv执行安装pip install langchain langchain-openai playwright python-dotenv版本方面本示例基于较新的 LangChain 稳定版本编写具体以你安装时的官方依赖为准。如果你之前使用过initialize_agent需要注意新版推荐使用create_react_agent后面的代码会使用新写法。4.3 安装 Playwright 浏览器Playwright 安装依赖包后还需要下载 Chromium 内核playwright install chromium如果你的机器在 Linux 服务器上推荐一步到位安装系统依赖playwright install --with-deps chromium验证浏览器是否安装成功python -m playwright --version到这里环境基本就绪。下面开始写代码。5. 完整代码实现从工具封装到 Agent 执行5.1 项目结构为了贴近工程习惯我们把工具和 Agent 入口拆成两个文件web_agent/ ├── tools/ │ ├── __init__.py │ └── browser_tools.py ├── web_agent.py ├── requirements.txt └── .env.example5.2 定义浏览器工具文件路径web_agent/tools/browser_tools.py# 文件路径web_agent/tools/browser_tools.py from langchain_core.tools import tool from playwright.sync_api import sync_playwright tool def search_bing(query: str) - str: 在必应搜索引擎中搜索关键词返回前 5 条搜索结果的标题、链接和摘要。 参数 query 是搜索关键词例如 “LangChain Agent 教程”。 with sync_playwright() as p: browser p.chromium.launch(headlessTrue) page browser.new_page() page.goto(fhttps://www.bing.com/search?q{query}, timeout30000) page.wait_for_selector(li.b_algo, timeout15000) items page.query_selector_all(li.b_algo) results [] for idx, item in enumerate(items[:5], start1): title_el item.query_selector(h2 a) snippet_el item.query_selector(.b_caption p) title title_el.inner_text() if title_el else 无标题 href title_el.get_attribute(href) if title_el else snippet snippet_el.inner_text() if snippet_el else results.append(f{idx}. {title}\n {href}\n {snippet}) browser.close() if not results: return 没有搜索到有效结果可能是页面结构变化或请求被拦截。 return \n\n.join(results) tool def open_and_extract(url: str, selector: str body) - str: 打开指定 URL并提取页面中与 CSS 选择器匹配的文本内容。 返回内容最多 2000 字符适合读取文章正文或页面关键区域。 with sync_playwright() as p: browser p.chromium.launch(headlessTrue) page browser.new_page() page.goto(url, timeout30000) page.wait_for_load_state(domcontentloaded) element page.query_selector(selector) text element.inner_text() if element else browser.close() return text[:2000] if text else 页面没有匹配到内容。 tool def click_and_read(url: str, button_text: str, result_selector: str) - str: 打开页面后点击指定文字的按钮再读取结果区域文本。 适合演示页面、测试环境中的交互场景例如点击“查询”“搜索”“确定”。 with sync_playwright() as p: browser p.chromium.launch(headlessTrue) page browser.new_page() page.goto(url, timeout30000) page.get_by_role(button, namebutton_text).click(timeout10000) page.wait_for_selector(result_selector, timeout10000) text page.inner_text(result_selector) browser.close() return text[:2000] if text else 点击后没有读取到结果。这段代码里工具的定义很关键tool装饰器是 LangChain 提供的注册方式会自动读取函数签名和 docstring生成给模型看的工具描述。每个工具返回的是纯文本因为模型的输入输出都是文本。把结构化的页面内容压缩成“前几条标题链接摘要”的文本能让模型更快聚焦。headlessTrue表示无头模式不会弹出浏览器窗口。想观察页面操作过程时可以改成headlessFalse。5.3 创建 LLM 与 Agent文件路径web_agent/web_agent.py# 文件路径web_agent/web_agent.py import os from dotenv import load_dotenv from langchain.agents import AgentExecutor, create_
返回列表