如何抓取 Google AI Mode:2025 年详细指南

发布: (2025年12月17日 GMT+8 20:34)
14 min read
原文: Dev.to

Source: Dev.to

Article Image

Introduction

Google AI Mode 已成为目前最快速、最全面的 AI 搜索体验之一。不同于像 ChatGPT 和 Claude 这类依赖训练数据的独立聊天机器人,AI Mode 使用实时的 Google 搜索结果,并采用 “query fan‑out” 技术在实时中同时搜索多个数据源。由于 Gemini AI 模型和搜索基础设施均由 Google 开发,系统能够无缝整合 Google Search、Lens 和 Image Search 的能力,提供异常快速的性能。

对于 SEO 专业人士和企业而言,AI Mode 代表了 用户发现内容方式的关键转变。这一新兴领域被称为 GEO(Generative Engine Optimization,生成式引擎优化),其重点在于出现在 AI 生成的响应中,而非传统的搜索结果。与传统的前 10 名排名不同,AI Mode 从更广泛的来源池中抽取信息,为品牌提供了即使未在首页排名也能被展示的机会。当你的品牌出现在这些 AI 响应中,它可以:

  • 带来流量
  • 生成合格的潜在客户
  • 在用户正研究解决方案的关键时刻影响购买决策

跟踪 AI Mode 的可见性正迅速变得 与监控传统搜索排名同等重要

在本文中,我们将探讨 抓取 Google AI Mode 结果的方法。我们将从使用 Playwright 和代理服务器的自定义抓取器开始,然后介绍一种更具可扩展性、面向生产环境的解决方案,该方案在大规模下能够可靠运行且无需持续维护。

Google AI 模式包含的内容

让我们先了解 Google AI 模式提供的信息。它包含以下数据点:

  • Prompt – 用户的查询
  • Answer – AI 生成的响应
  • Links – 响应中引用的 URL
  • Citations – 指向来源页面的链接

最重要的是,AI 模式的响应会因地区而异。相同的查询在美国、法国或其他任何地区搜索时会返回不同的结果。如前所述,所有这些数据点以及本地化响应的能力对于 GEO 和 AI 搜索跟踪 至关重要。

在本文中,我们将使用 Python 作为主要编程语言。所示技术可以根据需要适配到其他语言。有了这些背景知识,让我们从第一种方法——编写自定义代码——开始。

抓取 Google AI 模式的挑战

简单的实现方式无法用于抓取 AI 模式,原因有以下几点:

挑战 1 – Google 的反抓取检测

  • 没有使用代理的请求几乎会立即被验证码拦截。
  • 使用高级代理服务(例如 Residential Proxies)可以解决大多数拦截问题,但仍需预期偶尔出现验证码以及页面加载缓慢。

挑战 2 – 页面布局更改会导致全部失效

Google 经常更新页面布局和 HTML 选择器。你的选择器不可避免地会失效,从而导致抓取失败。偶尔抓取时这可能还能应付,但如果是生产环境(每日数百次查询),不断更新选择器将成为巨大的维护负担。

挑战 3 – 地理位置和语言不匹配

AI 模式的响应高度依赖地区,因此选择具有正确地理位置的代理对于获取准确结果至关重要。一些代理提供商允许你指定代理的地理位置,这使它们非常适合此类场景。此外,你还需要在请求中设置 Accept-Language 头,以匹配目标语言环境。

挑战 4 – 更长且高维护成本的代码

上述挑战导致代码变得复杂,需要持续维护:高质量的代理、选择器更新、性能监控以及资源密集型的浏览器(Playwright/Selenium),这些都会消耗大量 CPU 和内存。维护成本很快超出最初预期,使得自定义抓取器在生产环境中变得不切实际。

Source:

自定义 AI 模式网络爬虫

要创建 Google AI 模式爬虫,你有三种流行的 无头浏览器 选项(请参见链接页面上的对比表):Selenium、Playwright 和 Puppeteer。我们将重点介绍 Playwright,因为它流行、易用,并为现代网页抓取提供了多项优势。

安装 Playwright 的隐身版

pip install playwright-stealth

注意: 隐身插件有助于绕过 Google 的部分机器人检测机制。

下面的代码在今天可以正常工作,但由于选择器更改、封锁问题以及前文讨论的其他因素,预计会随时间失效。

import json
from playwright.sync_api import sync_playwright
from playwright_stealth import Stealth

query = "most comfortable sneakers for running"

with sync_playwright() as p:
    # 启动带有隐身功能的无头 Chromium 浏览器
    browser = p.chromium.launch(headless=True)
    context = browser.new_context()
    Stealth(context)                     # 应用隐身技巧

    # 设置代理和地区(示例值 – 请替换为你自己的)
    context.set_default_navigation_timeout(60000)
    context.set_extra_http_headers({
        "Accept-Language": "en-US,en;q=0.9"
    })
    # 如需使用代理,请取消注释并配置:
    # context = browser.new_context(proxy={"server": "http://my-proxy:3128"})

    page = context.new_page()

    # 访问 Google 并触发 AI 模式
    page.goto("https://www.google.com")
    page.wait_for_load_state("networkidle")

    # 接受 Cookie / 关闭弹窗(如果出现)
    try:
        page.click("text=I agree")
    except Exception:
        pass

    # 输入查询并回车
    page.fill("input[name='q']", query)
    page.keyboard.press("Enter")
    page.wait_for_load_state("networkidle")

    # 点击 “AI Mode” 按钮(选择器可能会变更)
    try:
        page.click("text=AI Mode")
        page.wait_for_load_state("networkidle")
    except Exception as e:
        print("AI Mode button not found:", e)

    # 提取答案、链接和引用
    result = {
        "prompt": query,
        "answer": None,
        "links": [],
        "citations": []
    }

    # 以下选择器仅为示例 – 请检查页面获取当前的选择器
    try:
        result["answer"] = page.inner_text("css=div[data-tts='answer']")
    except Exception:
        pass

    # 提取答案中的链接
    link_elements = page.query_selector_all("css=div[data-tts='answer'] a")
    for el in link_elements:
        href = el.get_attribute("href")
        if href:
            result["links"].append(href)

    # 提取引用 URL(通常位于 AI 响应底部)
    citation_elements = page.query_selector_all("css=div[data-tts='citation'] a")
    for el in citation_elements:
        href = el.get_attribute("href")
        if href:
            result["citations"].append(href)

    print(json.dumps(result, indent=2))

    # 清理资源
    context.close()
    browser.close()

关键要点

  1. 代理与地区 – 使用带有正确地理位置的住宅代理,并设置 Accept-Language 请求头。
  2. 隐身playwright-stealth 包有助于降低被标记为机器人的概率。
  3. 选择器维护 – 定期检查 CSS/XPath 选择器;Google 经常更改它们。
  4. 错误处理 – 将交互代码放在 try/except 块中,以优雅地处理 CAPTCHA 或缺失元素。

后续步骤

  • 规模化 – 将爬虫迁移到基于队列的架构(例如 RabbitMQ + 工作池),以并发处理大量查询。
  • CAPTCHA 解决 – 集成第三方 CAPTCHA 解决服务,以应对偶尔出现的挑战。
  • 监控 – 为选择器失效、延迟增加或代理被封等情况设置警报。

通过遵循上述方法,并时刻关注 Google 频繁的 UI 变化,你可以构建一个功能完善、可投入生产的 AI 模式爬虫。

可用于提取 Google AI 模式结果的生产就绪管道。

Google AI‑模式 抓取器 (Playwright)

import json
from playwright.sync_api import sync_playwright
from playwright_stealth import Stealth

query = "your search query here"

with sync_playwright() as p:
    browser = p.chromium.launch(
        headless=False,
        args=[
            "--disable-blink-features=AutomationControlled",
            "--disable-dev-shm-usage",
            "--no-sandbox",
        ],
        # Uncomment this to use proxies.
        # proxy={
        #     "server": "http://pr.oxylabs.io:7777",
        #     "username": "customer-USERNAME",
        #     "password": "PASSWORD",
        # }
    )
    context = browser.new_context(
        user_agent=(
            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) "
            "AppleWebKit/537.36 (KHTML, like Gecko) "
            "Chrome/143.0.0.0 Safari/537.36"
        )
    )
    page = context.new_page()
    Stealth().use_sync(page)

    page.goto(
        f"https://www.google.com/search?q={query.replace(' ', '+')}"
        "&udm=50&hl=en&gl=US"
    )
    page.wait_for_load_state("networkidle")

    container = None
    text_content = ""

    # Look for a suitable result container.
    candidates = page.locator("#search div, #rso > div, div[role='main'] div").all()
    for candidate in candidates[:30]:
        if not candidate.is_visible():
            continue
        text = candidate.inner_text()
        if len(text) > 200 and "http" not in text[:100]:
            container = candidate
            text_content = text
            break

    # Fallback: try to locate the query text directly.
    if not container:
        match = page.get_by_text(query).first
        if match.is_visible():
            container = match.locator("xpath=./ancestor::div[3]")
            text_content = container.inner_text()

    # Final fallback: use the whole page body.
    if not container or len(text_content) < 100:
        container = page.locator("body")
        text_content = page.inner_text("body")

    # Extract links from the chosen container.
    links = []
    if container:
        for link in container.locator("a").all():
            href = link.get_attribute("href")
            title = link.inner_text()
            if href and href.startswith("http"):
                links.append({"title": title.strip(), "url": href})

    output_data = {
        "content": text_content.strip(),
        "links": list({l["url"]: l for l in links}.values()),
    }

    print(json.dumps(output_data, indent=2))

    with open("ai_mode_data.json", "w") as f:
        json.dump(output_data, f, indent=2)

    browser.close()
print("Done!")

运行上述代码后,将会生成一个 JSON 文件,其中包含抓取到的 AI‑Mode 响应内容及其引用。
注意: CAPTCHA 或其他拦截措施可能会导致代码执行受阻。

最佳方案:AI‑Mode 抓取 API

自定义代码往往过于复杂、冗长且不可靠。更简便的做法是使用像 Oxylabs Web Scraper API 这样的专用服务,它内置对 Google AI‑Mode 抓取的支持。该 API 为您处理代理、浏览器渲染、验证码以及选择器变化等问题。

安装 requests

pip install requests

最小化 API 示例

import json
import requests

# API 参数。
payload = {
    "source": "google_ai_mode",
    "query": "most comfortable sneakers for running",
    "render": "html",
    "parse": True,
    "geo_location": "United States",
}

response = requests.post(
    "https://realtime.oxylabs.io/v1/queries",
    # 免费试用可在 dashboard.oxylabs.io 获得
    auth=("USERNAME", "PASSWORD"),
    json=payload,
)
response.raise_for_status()
print(response.text)

with open("AI_Mode_scraper_data.json", "w") as f:
    json.dump(response.json(), f, indent=2)

print("Done!")

执行后,保存的 JSON 文件将包含类似下图的结构化结果(为简洁起见折叠了链接):

JSON 结果

理解 payload

payload = {
    "source": "google_ai_mode",
    "query": "most comfortable sneakers for running",
    "render": "html",
    "parse": True,
    "geo_location": "United States",
}
  • source – 选择要使用的抓取器;google_ai_mode 获取 AI‑Mode 结果。
  • render – 返回完整渲染后的 HTML,确保所有动态内容已加载。
  • parse – 启用自动数据解析,这样您就不需要自定义解析器。
  • geo_location – 本地化结果。您可以指定任意国家、州、市,甚至精确坐标,例如:
"geo_location": "New York,New York,United States"

只需一次订阅,您即可访问许多其他预构建的来源(Google 搜索、Amazon、ChatGPT 等),并且能够在不担心封锁、中断或维护的情况下,轻松扩展到数百甚至数千次请求。

退出全屏模式

欲了解更多详情,请参阅 AI Mode scraper documentation

使用网页抓取 API 的优势

Google AI Mode 抓取 API 让 AI 响应提取变得轻而易举,无需编写自定义代码。原因如下:

  • 无需维护基础设施 – 不需要管理浏览器,不需要自行编写重试逻辑,也不需要自行实现 IP 轮换。只需发送 API 请求,即可获取结果。
  • 内置高级代理 – 该 API 配备了由智能机器学习驱动的代理服务器,引擎会为你处理代理管理和 CAPTCHA 验证。
  • 对 Google 布局更改的弹性 – 当 Google 更新 UI 时,Oxylabs 会更新其后端。你的代码无需任何改动。

最终思考

抓取 Google AI 模式可以是直接的,也可以是具有挑战性的,这取决于你选择的方法。

  • 编写自己的代码可以让你拥有完全的控制权,但随着时间推移,维护工作会变得沉重。
  • 定制化解决方案需要:
    • 智能的浏览器环境管理
    • 绕过严格的反抓取系统的逻辑
    • 集成高质量的代理服务器
    • 自定义数据解析
    • 持续的维护,以及其他诸多考量。

Oxylabs Web Scraper API 为你处理所有这些难题。只需发送请求,即可在几秒钟内收到解析后的数据。该 API 还内置了针对 Google Search、Amazon、ChatGPT 等热门站点的预构建抓取器和解析器,让你无需为每个网站单独构建和维护解决方案。

Back to Blog

相关文章

阅读更多 »

仓库利用的权威指南

引言 仓库本质上只是一个 3‑D 盒子。利用率只是衡量你实际使用了该盒子多少的指标。虽然物流 c...