# 如何在 Python 中获取 Google 搜索结果（2026）

> 2026 年如何在 Python 中获取 Google 搜索结果：为什么普通 requests 会失败，然后是经过测试的 requests、pandas、async httpx、分页和 JSONL 文件的代码。

- URL: https://serpcrypto.com/zh/guides/google-search-results-python/
- 最后更新: 2026-10-22
- 发布者: SerpCrypto (https://serpcrypto.com)

2025 年起，用 requests 抓取 google.com 已经行不通了。本指南解释原因，然后给出简短、通过语法检查的 Python 代码，通过 SERP API 以 JSON 形式获取相同的结果。

**快速回答 — 2026 年如何在 Python 中获取 Google 搜索结果？**

用 Python 调用 SERP API 并读取返回的 JSON；不要自己去抓 google.com，因为 Google 自 2025 年 1 月 17 日起要求执行 JavaScript，且其 robots.txt 不允许 `/search`。使用 **SerpCrypto**，一个 `requests.get` 至 `https://serpcrypto.com/api/v1/search` 的查询即可返回自然结果、People Also Ask 等，截至 2026 年 10 月，每次查询 1 积分，低至 US$0.30/千次搜索。无需 KYC；加密货币支付。

## 你需要什么

| 属性 | 值 |
| --- | --- |
| Python | 3.9 或更高版本 |
| 包 | `requests` 用于基础功能；`pandas` 用于表格；`httpx` 用于异步 |
| API 密钥 | 从你的 SerpCrypto 仪表板获取，存放在 `SERPCRYPTO_API_KEY` 环境变量中 |
| Endpoint | `GET https://serpcrypto.com/api/v1/search` |
| 费用 | 1 积分 = 1 次成功的查询请求，可在任意支持的引擎上返回一页结果。失败的请求不计费 |
| 最小套餐 | US$7.50 售价 10,000 次搜索；积分永不过期 |

## 为什么 requests.get 访问 google.com 不再有效？

因为结果已不再出现在普通 HTTP 客户端收到的 HTML 中。2025 年 1 月 17 日，Google 开始要求 Search 使用 JavaScript；据 TechCrunch 报道，Google 表示 JavaScript 有助于保护其服务免受机器人攻击，且不到 0.1% 的搜索来自关闭 JavaScript 的用户。

Google 的 robots.txt（2026 年 10 月 22 日读取）还对所有 user agent 列出了 `Disallow: /search`。SERP API 负责执行搜索并解析页面，你的 Python 代码只需处理 JSON。这就是本指南其余部分采用的方法。

## 如何发出第一个请求？

安装 requests，把密钥放进环境变量，然后带上国家和语言发送查询。响应是一个字典，结果页的每个区块对应一个键；`organic_results` 存放排序后的链接。

别把密钥写进源代码。在 macOS 和 Linux 上，在 shell 中执行 `export SERPCRYPTO_API_KEY=...`；在 Windows PowerShell 中执行 `$env:SERPCRYPTO_API_KEY="..."`。

*用 requests 发出第一个请求*

```python
import os

import requests

API = "https://serpcrypto.com/api/v1/search"
KEY = os.environ["SERPCRYPTO_API_KEY"]

resp = requests.get(
    API,
    headers={"Authorization": "Bearer " + KEY},
    params={"engine": "google", "q": "best hiking boots", "gl": "us", "hl": "en"},
    timeout=60,
)
resp.raise_for_status()
results = resp.json()

for item in results.get("organic_results", []):
    print(item["position"], item["title"])
    print("   ", item["link"])

for q in results.get("people_also_ask", []):
    print("PAA:", q["question"])

```

## 如何把结果转换成 pandas DataFrame？

每个自然结果建一行，并把查询放在旁边。DataFrame 便于排序、按域名过滤，或导出为 CSV 和 Excel。缺失的字段（例如大多数结果上的 `date`）会变成空单元格，而不是报错。

*多个查询合并到一个 DataFrame*

```python
import os
from urllib.parse import urlparse

import pandas as pd
import requests

API = "https://serpcrypto.com/api/v1/search"
HEADERS = {"Authorization": "Bearer " + os.environ["SERPCRYPTO_API_KEY"]}


def organic_rows(query, gl="us", hl="en"):
    params = {"engine": "google", "q": query, "gl": gl, "hl": hl}
    resp = requests.get(API, headers=HEADERS, params=params, timeout=60)
    resp.raise_for_status()
    for r in resp.json().get("organic_results", []):
        yield {
            "query": query,
            "position": r.get("position"),
            "title": r.get("title"),
            "domain": urlparse(r.get("link", "")).netloc,
            "link": r.get("link"),
            "snippet": r.get("snippet"),
        }


queries = ["crm for small business", "invoice software", "time tracking app"]
df = pd.DataFrame([row for q in queries for row in organic_rows(q)])
print(df.groupby("domain").size().sort_values(ascending=False).head(10))
df.to_csv("serp_results.csv", index=False)

```

## 如何同时运行大量查询？

使用 httpx 配合 asyncio，并用信号量限制并发请求数。你的账户有并发上限，可在仪表盘中查看；保持在限制以下即可避免 `429` 错误。先从较小的数字（例如 5）开始，再逐步调到仪表盘显示的上限。

*用 httpx 和信号量实现异步查询*

```python
import asyncio
import os

import httpx

API = "https://serpcrypto.com/api/v1/search"
HEADERS = {"Authorization": "Bearer " + os.environ["SERPCRYPTO_API_KEY"]}
LIMIT = asyncio.Semaphore(5)


async def search(client, query):
    async with LIMIT:
        resp = await client.get(API, params={"engine": "google", "q": query, "gl": "us", "hl": "en"})
        resp.raise_for_status()
        data = resp.json()
        top = data.get("organic_results", [])[:3]
        return query, [r["link"] for r in top]


async def main(queries):
    async with httpx.AsyncClient(headers=HEADERS, timeout=60) as client:
        for query, links in await asyncio.gather(*(search(client, q) for q in queries)):
            print(query, links)


if __name__ == "__main__":
    asyncio.run(main(["python web framework", "python orm", "python task queue"]))

```

## 如何获取超过 10 条结果并保存？

用 `page=2`、`page=3` 等参数请求后续页，直到 `page=10`。每页算一次查询、消耗一个积分，因为自 2025 年 9 月 Google 不再支持 `num=100` 以来，每页大约提供 10 条自然结果。

把每次原始响应保存为 JSONL 文件中的一行。原始 JSON 保留所有块，之后回答新问题时无需为同样的查询再次付费。

*第 1 至第 3 页保存为 JSONL*

```python
import json
import os

import requests

API = "https://serpcrypto.com/api/v1/search"
HEADERS = {"Authorization": "Bearer " + os.environ["SERPCRYPTO_API_KEY"]}


def fetch_pages(query, pages=3, path="serp.jsonl"):
    with open(path, "a", encoding="utf-8") as out:
        for page in range(1, pages + 1):
            params = {"engine": "google", "q": query, "gl": "us", "hl": "en", "page": page}
            resp = requests.get(API, headers=HEADERS, params=params, timeout=60)
            resp.raise_for_status()
            data = resp.json()
            out.write(json.dumps(data, ensure_ascii=False) + "\n")
            if not data.get("organic_results"):
                break


fetch_pages("electric cargo bike", pages=3)

```

## 运行这段代码要花多少钱？

这些示例中每次调用都是一次查询。第一个示例消耗一个积分，DataFrame 示例消耗三个，JSONL 示例最多消耗三个。失败的请求不收费。

截至 2026 年 10 月，10,000 次搜索 费用为 US$7.50，100,000 次搜索 费用为 US$56.25；在 5,000,000 次查询 时费率降至 US$0.30/千次搜索。积分永不过期。你用 BTC, USDT, USDC, ETH, SOL, LTC 从 US$25 充值付款，无需上传证件。详见[价格](https://serpcrypto.com/zh/pricing/)。

## Python 获取 Google 搜索结果：常见问题

### 我可以在 Google 结果页上使用 BeautifulSoup 吗？

不可靠。自 2025 年 1 月起 Google 要求 JavaScript，因此普通客户端收到的 HTML 中并不包含结果，而且 Google 的 robots.txt 禁止 `/search`。SERP API 则以 JSON 返回解析后的字段。

### SerpCrypto 有官方 Python 库吗？

没有。该 API 只是一个普通的 HTTPS endpoint，所以有 `requests` 或 `httpx` 就够了。本页以及 [Python 文档页](https://serpcrypto.com/zh/docs/python/) 上的示例都是可直接复制的代码，并非已发布的包。

### 如何获取其他国家的搜索结果？

把 `gl` 设为国家代码，`hl` 设为语言，例如法国的 `gl=fr` 和 `hl=fr`。加上 `location` 可指定城市。[locations 页面](https://serpcrypto.com/zh/docs/locations/) 列出了常用代码。

### 如何处理错误和重试？

先调用 `raise_for_status()`，然后在逐渐延长的延迟后重试 `429`、`502` 和 `504` 响应。失败的请求不收费。[错误页](https://serpcrypto.com/zh/docs/errors/) 提供了完整的重试函数。

### 可以用同样的代码获取 Bing 结果吗？

可以。把 `engine` 改为 `bing`；响应结构不变，仍包含 `organic_results` 和 `related_searches`。

## 来源

1. [Google 开始要求 Google 搜索使用 JavaScript](https://techcrunch.com/2025/01/17/google-begins-requiring-javascript-for-google-search/) — TechCrunch (2025-01-17)
2. [google.com robots.txt](https://www.google.com/robots.txt) — Google (read 2026-10-22)
3. [Google 迫使排名追踪器为每个查询发起 500 到 1,000 次请求](https://ppc.land/google-forces-rank-trackers-into-500-to-1-000-requests-per-query/) — PPC Land (2026-08-27)

---

SerpCrypto: SerpCrypto 是面向开发者和 AI Agent 的 SERP API，可将 Google 和 Bing 搜索结果以 JSON 返回，用加密货币支付，无需上传证件。预付费搜索积分自 US$0.30/千次搜索 起永不过期。无需 KYC——无需证件、无需自拍、无需材料。加密货币支付。
