Google AI Mode 改变了搜索结果的呈现方式。取代十条蓝色链接的,是一个 AI 回答界面:针对你的查询返回一段书面答复,下方列出一组引用来源,侧边还有一系列相关链接。对于追踪 Google 就某一话题所给出答案的人来说,这是一个全新且有价值的数据集:不仅能看到谁排名靠前,还能看到绑定在某个查询上的实际答案,以及 Google 选择作为支撑的页面。
本指南将向你展示如何以可靠的方式抓取 Google AI Mode。你将构建一个小而可运行的 Python 脚本,通过 Crawling API 获取公开的 AI Mode 结果。该 API 在可信 IP 后方渲染 JavaScript 密集型页面,然后将 AI 答案、引用来源和相关链接提取为整洁的结构化 JSON。获取和轮换均由 API 处理,你可以专注于数据本身,而无需费力维护无头浏览器和代理池。
Google AI Mode 是什么,为什么要抓取它
AI Mode 是 Google 搜索内部的生成式答案层。通过在普通搜索 URL 中添加 udm=50 参数即可访问,该参数告知 Google 返回其 AI 生成的答复,而非经典结果页面。答复由三部分构成,这三部分是抓取的关键所在:答案文本本身、Google 附加到该答案的引用来源,以及与查询相关的更广泛参考链接集。
这种结构正是它值得收集的原因。你可以追踪 Google 对某个查询的答案随时间的变化,了解它引用了哪些域名及引用频率,并将其输入 SEO 研究或内容工作流。这与构建任何搜索引擎数据工具属于同类问题,只不过数据载体是一个答案及其来源,而非一个排名列表。
udm 参数用于选择 Google 搜索的垂直类别。udm=50 触发 AI Mode,就像其他值可以切换到图片或新闻搜索一样。将其与查询和地区一起附加到标准的 google.com/search URL 上,Google 就会为该查询返回 AI 答案界面。
你将构建什么
一个简短的 Python 脚本,接收一个搜索查询,构建 AI Mode URL,通过启用 JavaScript 渲染的 Crawling API 发送,并将渲染结果解析为一个包含三个字段的 JSON 对象:答案文本、引用来源列表以及相关链接列表。每个代码片段都可以在放入你的 token 后直接运行,无论是针对单个查询还是循环处理数百个查询,代码逻辑相同。
为什么普通请求会失败
如果你用普通 HTTP 客户端请求 AI Mode URL,会得到状态 200 的响应,但响应体中没有任何答案内容。有两个因素对你不利。第一,AI Mode 在浏览器中渲染:答案和引用来源在页面 JavaScript 运行后才流式加载进来,因此初始 HTML 是一个空壳。第二,Google 对自动化流量的反应非常快速。不像真实访客的数据中心 IP 和请求模式,在看到渲染后的答案之前就会被 CAPTCHA 或封锁拦下。
因此,一个可用的 AI Mode 爬虫需要在一次请求中同时满足两点:一个实际渲染页面的浏览器,以及一个 Google 视为真实访客的 IP。你可以自行用无头浏览器加轮换住宅代理来实现,但将两者组合起来并持续维护是大部分的工作量所在。Crawling API 将两者融合进一次调用:发送带 JavaScript token 的 URL,它在可信 IP 后方渲染页面,并将已完成的 HTML 交还给你解析。
Crawlbase 提供两种 token 类型。普通 token 获取静态 HTML;JavaScript (JS) token 先在真实浏览器中渲染页面。AI Mode 是客户端渲染的,因此此处需要 JS token。使用普通 token 返回的是与普通请求相同的空壳,没有任何答案文本可提取。
第一步:构建 AI Mode URL
流水线的入口是一个将查询转换为有效 AI Mode URL 的函数。你设置 udm=50 以选择 AI Mode,在 q 中传入查询,并添加 gl 和 hl 以控制国家和语言,确保每次运行的结果一致。
from urllib.parse import urlencode, quote_plus def build_ai_mode_url(query, gl="us", hl="en"): if not query or not query.strip(): raise ValueError("query must be non-empty") params = { "udm": "50", "q": query.strip(), "gl": gl, "hl": hl, } query_string = urlencode(params, quote_via=quote_plus) return f"https://www.google.com/search?{query_string}" print(build_ai_mode_url("best ai tools for developers"))
传入一个查询,即可得到一个一致的 AI Mode URL。从这里开始,其余的工作流程是一条直线:通过 Crawling API 发送 URL,然后将渲染结果规范化为你的系统可以使用的结构化字段。
第二步:通过 Crawling API 获取已渲染的页面
有了 URL,接下来获取已渲染的页面。你需要传入两个对 AI 界面至关重要的选项:ajax_wait 告知 API 等待异步内容加载完毕,page_wait 在加载后固定等待指定毫秒数,以便流式传输的答案和引用来源在页面被捕获前有时间出现。五秒是一个合理的起点,如果答案返回内容较少可适当增加。
from crawlbase import CrawlingAPI api = CrawlingAPI({"token": "YOUR_CRAWLBASE_JS_TOKEN"}) def fetch_html(target_url): options = {"ajax_wait": "true", "page_wait": 5000} response = api.get(target_url, options) return response["body"].decode("utf-8") url = build_ai_mode_url("best ai tools for developers") html = fetch_html(url) print(html[:500])
运行此代码,你应当看到包含 AI 答案块的真实标记,而非普通请求返回的空壳。这可以在编写任何选择器之前确认渲染是否正常工作。你不再需要处理浏览器状态或反爬挑战;你已经拥有可供解析的已完成 HTML。
AI Mode 需要在一次调用中同时完成页面渲染和可信 IP 访问。Crawling API 接收 JS token,在真实浏览器中运行页面,在服务端轮换住宅 IP,并将已完成的 HTML 交给你,省去了自行运营无头浏览器集群和代理池的麻烦。先用免费额度对公开查询进行测试。
第三步:提取答案、引用来源和链接
有了已渲染的 HTML,将其加载到解析器中并提取三个关键字段。使用 BeautifulSoup 读取答案文本,然后遍历引用来源和链接块以收集各自的 URL 和标题。AI Mode 标记并非公开合约,因此将下面的选择器视为起始模板:在浏览器开发者工具中检查一个实时 AI Mode 页面,并与当前布局对照确认。
from bs4 import BeautifulSoup def extract_ai_mode(html): soup = BeautifulSoup(html, "html.parser") answer_block = soup.select_one('div[data-rl="ai-mode"], div.ai-response') response_text = answer_block.get_text(" ", strip=True) if answer_block else "" citations = [] for cite in soup.select('a.ai-citation, div.citation a[href]'): href = cite.get("href", "") if href.startswith("http"): citations.append({ "url": href, "title": cite.get_text(strip=True), }) links = [] for link in soup.select('div.related-links a[href^="http"]'): links.append({ "url": link["href"], "title": link.get_text(strip=True), }) return { "response_text": response_text, "citations": citations, "links": links, }
每个字段都直接对应 AI Mode 呈现答案的方式。response_text 是可以存储、比较或展示的生成式答案。citations 是 Google 附加以支撑该答案的来源,每条均带有 URL 和标题。links 是围绕查询的更广泛相关结果集。刻意保持 schema 精简:三个稳定字段足以覆盖大多数仪表盘和数据流水线,而不会将你锁定在一个随时可能变化的标记上。
Google 不公开 AI Mode 的稳定 class 名称,标记会在没有通知的情况下发生变化。当提取开始返回空字符串时,重新检查实时 AI Mode 页面并更新选择器。这对于任何生产爬虫来说都是正常的维护工作,并不意味着出了什么问题。在输出结果旁边保留一个简短的原始 HTML 样本,可以轻松判断问题是出在你的解析器还是上游变化上。
第四步:串联起来并保存结果
现在将三个步骤组合成一个可运行的脚本。它构建 URL,获取已渲染的页面,提取字段,并将结构化结果写入一个可供检查或下游加载的 JSON 文件。
import json from urllib.parse import urlencode, quote_plus from crawlbase import CrawlingAPI from bs4 import BeautifulSoup api = CrawlingAPI({"token": "YOUR_CRAWLBASE_JS_TOKEN"}) def build_ai_mode_url(query, gl="us", hl="en"): params = {"udm": "50", "q": query.strip(), "gl": gl, "hl": hl} return f"https://www.google.com/search?{urlencode(params, quote_via=quote_plus)}" def fetch_html(target_url): options = {"ajax_wait": "true", "page_wait": 5000} response = api.get(target_url, options) return response["body"].decode("utf-8") def extract_ai_mode(html): soup = BeautifulSoup(html, "html.parser") answer_block = soup.select_one('div[data-rl="ai-mode"], div.ai-response') response_text = answer_block.get_text(" ", strip=True) if answer_block else "" citations = [ {"url": c["href"], "title": c.get_text(strip=True)} for c in soup.select('a.ai-citation, div.citation a[href^="http"]') ] links = [ {"url": l["href"], "title": l.get_text(strip=True)} for l in soup.select('div.related-links a[href^="http"]') ] return {"response_text": response_text, "citations": citations, "links": links} def scrape_ai_mode(query, gl="us", hl="en"): url = build_ai_mode_url(query, gl, hl) html = fetch_html(url) data = extract_ai_mode(html) data["query"] = query return data if __name__ == "__main__": result = scrape_ai_mode("best ai tools for developers") with open("ai_mode.json", "w") as f: json.dump(result, f, indent=2) print(json.dumps(result, indent=2))
用 python scraper.py 运行,结构化的答案将写入 ai_mode.json 并回显到控制台。如果你想将其集成到自己的应用中,scrape_ai_mode 函数也是唯一需要导入的地方:传入一个查询,就能获得相同的结构化字典,无需额外的解析工作。
输出结果示例
结果是一个包含答案文本和两个列表的单一对象。一个精简示例:
{ "query": "best ai tools for developers", "response_text": "Popular AI tools for developers include code assistants, ...", "citations": [ { "url": "https://example.com/ai-dev-tools", "title": "10 AI Tools for Developers" }, { "url": "https://example.org/coding-assistants", "title": "Best Coding Assistants" } ], "links": [ { "url": "https://example.net/dev-productivity", "title": "Developer Productivity Guide" } ] }
这个结构足以随时间追踪某个答案,统计 Google 最常引用哪些域名,或通过改变 gl 和 hl 来比较不同地区的答案差异。将答案文本与时间戳一起存储,就能得到一个简单的 Google 对某一查询的回应历史记录。
扩展到多个查询
单个查询只是演示;真实的工作任务需要处理一个列表。结构不变:循环查询,逐一抓取,收集结果行。在大量运行时需要重点关注的是保持不被封锁,因为 Google 会监控爬虫形态的流量。Crawling API 在每次调用时为你轮换 IP,所以下面的循环无需自行管理代理。
queries = [ "best ai tools for developers", "how does web scraping work", "python vs javascript for automation", ] results = [] for q in queries: try: results.append(scrape_ai_mode(q)) except Exception as err: print(f"Skipped {q}: {err}") with open("ai_mode_batch.json", "w") as f: json.dump(results, f, indent=2)
如果你倾向于将自己的流量通过轮换池路由,而不是端到端地使用 Crawling API,Smart AI Proxy(也称为 AI Proxy)可作为直接替换代理端点提供相同的住宅 IP 轮换功能。关于保持任何 Google 抓取健康运行的更广泛操作指南,请参阅如何轮换代理抓取 Google 搜索结果以及如何不被封锁地抓取网站。
常见问题与解决方案
抓取 Google 界面并非一劳永逸的工作。数据载荷会发生变化,你的解析器需要有足够的弹性。最常遇到的问题都比较直观:
-
答案文本为空。 如果
response_text返回空白,页面可能还未完成渲染。增大page_wait,确认你使用的是 JS token,并重新对照实时页面检查答案块选择器。 - 认证或额度错误。 在渲染之前失败的请求通常意味着 token 有误或余额不足。检查你的 JS token 是否正确、账户是否有额度,并查阅Google 向流量发起挑战时的 API 响应行为。
- 引用来源或链接缺失。 Google 会移动这些内容块。当它们不再匹配时,更新引用来源和链接选择器,并保留一个原始 HTML 样本,以便查看具体发生了什么变化。
当结果突然减少或看起来不同时,将最近的原始 HTML 样本与旧的对比。这通常能立刻告诉你,变化是在你的解析逻辑中还是在已渲染页面的上游。
抓取 Google AI Mode 是否合法?
抓取 Google AI Mode 是否被允许,取决于 Google 的服务条款、你所在的司法管辖区以及你对数据的使用方式。Google 的条款限制了对其服务的自动访问,因此无论你的工具多么谨慎,抓取行为都可能与这些条款相抵触。此处的代码并不改变这一点,只是让技术层面运作起来。在将此脚本指向生产流量之前,请阅读 Google 的服务条款和 robots.txt,并据此作出决定。
有几条值得坚守的原则。仅收集公开的 AI Mode 结果,即无需登录、任何人都可以看到的答案和来源。将你的请求频率保持在不会给 Google 系统造成负担的水平,并尊重其 robots.txt 所传达的速率预期。不要收集个人或私人数据,也不要尝试访问任何需要登录的内容。如果你计划商业性地使用这些数据,请获得许可或官方数据协议,而不是默认沉默即为同意。
本指南故意将范围限定在公开 AI Mode 结果,因为这是保持工作可辩护的边界。它不涵盖需要登录或访问私人数据的场景,不涉及账户或个人信息,也不包括任何绕过身份验证的尝试。如果你的项目需要超出公开答案界面之外的内容,正确的做法是与 Google 签订官方数据协议,而不是设计更聪明的爬虫。
核心要点
-
AI Mode 是一个新的数据集。
udm=50URL 返回的是 AI 答案及其引用来源和相关链接,而非一个排名列表,因此你收集的是绑定在查询上的答案。 - 普通请求返回空壳。 AI Mode 是客户端渲染的,且 Google 会拦截机器人,因此必须在可信 IP 后方渲染页面再解析。
-
一次调用处理两件事。 带 JS token 的 Crawling API 在服务端渲染页面并轮换 IP;
ajax_wait和page_wait控制等待答案的时长。 -
三个字段已足够。 将结果规范化为
response_text、citations和links,并保留原始 HTML 样本,以便区分解析问题与上游变化。 -
仅针对公开数据。 遵守 Google 的服务条款和
robots.txt,不要访问需要登录的内容或个人数据,不要绕过身份验证。
常见问题
Google 搜索 URL 中的 udm=50 是什么?
udm=50 是触发 Google AI Mode 的搜索参数。udm 值选择搜索垂直类别,50 对应的是返回 AI 答案界面的类别,而非经典链接列表。将其与查询、国家和语言一起附加到标准的 google.com/search URL 上,Google 就会为该查询返回 AI Mode 结果。
为什么普通请求从 Google AI Mode 获取不到答案?
因为 AI Mode 是客户端渲染的。答案和引用来源在页面 JavaScript 运行后才流式加载进来,所以原始 HTTP 请求返回的是状态 200 加上一个空壳。Google 还会迅速对自动化流量发起挑战。要获取真实答案,必须在可信 IP 后方渲染页面,这正是 Crawling API 的 JS token 为你处理的工作。
我需要普通 token 还是 JS token?
JS token。普通 token 获取的是静态 HTML,对于 AI Mode 来说,这与普通请求返回的空壳相同。JS token 先在真实浏览器中渲染页面,确保答案、引用来源和链接在解析器读取时已完整呈现。
我可以从 Google AI Mode 结果中提取哪些数据?
三个稳定字段可以覆盖大多数需求:生成式答案文本、Google 附加到该答案的引用来源(每条均带有 URL 和标题),以及围绕查询的更广泛相关链接集。保持 schema 精简可以让流水线更具弹性,因为你不会被锁定在 Google 随时可能变化的标记上。
我的选择器返回空字符串。发生了什么?
几乎可以肯定是 Google 的标记发生了变化。AI Mode 没有公开的稳定 class 名称,所以上个月有效的选择器可能已经失效。在浏览器开发者工具中重新检查实时 AI Mode 页面,并更新答案、引用来源和链接选择器。在输出结果旁边保留一个简短的原始 HTML 样本,可以轻松看出发生了什么变化。
抓取 Google AI Mode 是否合法?
这取决于 Google 的服务条款、你所在的司法管辖区以及你的目的,而 Google 的条款限制了自动访问。请严格限于公开的 AI Mode 结果,遵守 robots.txt 和速率预期,不要触碰需要登录的内容、个人数据或身份验证机制。如需商业性地使用,请获得许可或官方数据协议,而不是依赖爬虫。
大规模爬取任何站点,无需与基础设施对抗。
Crawlbase 负责处理代理、指纹和 CAPTCHA,让你的团队专注于交付数据流水线,而非维护爬取管道。1,000 次请求免费,无需信用卡。

