SerpAPI
Живая выдача Google в структурированном JSON: web, Maps, Shopping, News, Images,
YouTube, Scholar, Jobs, Trends. Один эндпоинт, движок выбирается параметром
engine. Капчи и прокси на стороне сервиса — браузер не нужен.
Ключ
SERPAPI_API_KEY из ~/.claude/.credentials.master.env, читать через
os.getenv. Каждый вызов списывает единицу квоты плана — при отладке не гоняй
цикл по страницам вслепую. Тарифы и лимиты → references/pricing-and-limits.md.
Вызов
import os, requests
def serp(engine: str, **params) -> dict:
r = requests.get("https://serpapi.com/search", params={
"api_key": os.getenv("SERPAPI_API_KEY"),
"engine": engine, "output": "json",
"hl": "en", "gl": "us", **params,
})
r.raise_for_status()
return r.json()
Есть официальная обёртка, но ставится она под неочевидным именем:
pip install google-search-results, а импорт при этом from serpapi import GoogleSearch. Возможностей она не добавляет — тот же GET с теми же параметрами.
Локальная бесплатная альтернатива
Для простого парсинга живой выдачи (без carousels/Maps/Shopping/Trends — за
структурой оставайся на SerpAPI) — self-hosted karust/openserp в Docker,
127.0.0.1:7000, 0 кредитов. Поддерживает Google/Yandex/Bing/DuckDuckGo.
DuckDuckGo/Bing работают из коробки; Google и особенно Yandex (которого
SerpAPI не отдаёт вообще) из коробки капчатся/ратлимитятся без прокси — нужен
--proxy/--2captcha_key на старте контейнера. Полные детали, эндпоинты, гочи
→ ~/.claude/skills/seo-machine-ru/SKILL.md, секция «Яндекс/Google SERP локально
(openserp)».
Движки: параметр запроса и ключ результатов
Ключ, под которым лежат результаты, из имени движка не выводится — угадаешь
неверно, получишь пустой список и решишь, что выдача пустая.
| engine |
запрос кладётся в |
результаты в |
google |
q |
organic_results + knowledge_graph, answer_box, related_questions, related_searches |
google_maps |
q |
local_results |
google_shopping |
q |
shopping_results |
google_news |
q |
news_results |
google_images |
q |
images_results (не image_) |
youtube |
search_query (не q) |
video_results |
google_scholar |
q |
organic_results |
google_jobs |
q |
jobs_results |
google_trends |
q |
interest_over_time, related_queries, related_topics |
google_videos, google_local, google_patents |
q |
распечатай results.keys() — здесь не зафиксировано |
Параметры, которые не угадываются
| Задача |
Параметр |
| Язык / страна выдачи |
hl=en, gl=us |
| Вторая страница |
start=10 (третья — 20) |
| Свежесть: день/неделя/месяц/год |
tbs=qdr:d / qdr:w / qdr:m / qdr:y |
| Вилка цен в Shopping |
tbs=mr:1,price:1,ppr_min:50 (и/или ppr_max:200) |
| Размер картинки |
tbs=isz:l (m средние, i иконки) |
| Тип картинки |
tbs=itp:photo (clipart, lineart) |
| Публикации от года (Scholar) |
as_ylo=2023 |
| Точка на карте |
ll=@55.75,37.61,15z — с @ и z-зумом; либо location=Moscow |
| Окно Trends |
date="today 12-m" (now 1-H, now 7-d, today 1-m) + data_type=TIMESERIES |
tbs — одна строка: несколько фильтров склеиваются через запятую, второе
присваивание затирает первое.
Вложенные поля ответа
Часть значений лежит глубже, чем кажется по названию:
- News:
source.name (не source)
- YouTube:
channel.name, thumbnail.static
- Scholar:
publication_info.summary, inline_links.cited_by.total,
PDF — resources[0].link (списка resources может не быть вовсе)
- Jobs:
detected_extensions.posted_at, detected_extensions.salary
- Shopping:
price — строка с валютой, число для сравнения — extracted_price
- Maps:
gps_coordinates, hours
Гочи
- Результаты кэшируются ~30 секунд: повтор идентичного запроса вернёт тот же
снимок. Если нужна свежесть после правки — меняй параметры, а не жми повтор.
- Локаль решает состав выдачи:
gl/hl меняют не только язык подписей, но и
набор блоков (answer_box, «People also ask» появляются не везде).
1---2name: serpapi-23description: Google Search API через SerpAPI (SERPAPI_API_KEY): выдача, Maps, Shopping, News, YouTube. Триггеры: «спарси выдачу гугла», «цены google shopping».4---56# SerpAPI78Живая выдача Google в структурированном JSON: web, Maps, Shopping, News, Images,9YouTube, Scholar, Jobs, Trends. Один эндпоинт, движок выбирается параметром10`engine`. Капчи и прокси на стороне сервиса — браузер не нужен.1112## Ключ1314`SERPAPI_API_KEY` из `~/.claude/.credentials.master.env`, читать через15`os.getenv`. Каждый вызов списывает единицу квоты плана — при отладке не гоняй16цикл по страницам вслепую. Тарифы и лимиты → `references/pricing-and-limits.md`.1718## Вызов1920```python21import os, requests2223def serp(engine: str, **params) -> dict:24 r = requests.get("https://serpapi.com/search", params={25 "api_key": os.getenv("SERPAPI_API_KEY"),26 "engine": engine, "output": "json",27 "hl": "en", "gl": "us", **params,28 })29 r.raise_for_status()30 return r.json()31```3233Есть официальная обёртка, но ставится она под неочевидным именем:34`pip install google-search-results`, а импорт при этом `from serpapi import35GoogleSearch`. Возможностей она не добавляет — тот же GET с теми же параметрами.3637## Локальная бесплатная альтернатива3839Для простого парсинга живой выдачи (без carousels/Maps/Shopping/Trends — за40структурой оставайся на SerpAPI) — self-hosted `karust/openserp` в Docker,41`127.0.0.1:7000`, 0 кредитов. Поддерживает Google/Yandex/Bing/DuckDuckGo.42DuckDuckGo/Bing работают из коробки; Google и особенно **Yandex** (которого43SerpAPI не отдаёт вообще) из коробки капчатся/ратлимитятся без прокси — нужен44`--proxy`/`--2captcha_key` на старте контейнера. Полные детали, эндпоинты, гочи45→ `~/.claude/skills/seo-machine-ru/SKILL.md`, секция «Яндекс/Google SERP локально46(openserp)».4748## Движки: параметр запроса и ключ результатов4950Ключ, под которым лежат результаты, из имени движка не выводится — угадаешь51неверно, получишь пустой список и решишь, что выдача пустая.5253| engine | запрос кладётся в | результаты в |54|---|---|---|55| `google` | `q` | `organic_results` + `knowledge_graph`, `answer_box`, `related_questions`, `related_searches` |56| `google_maps` | `q` | `local_results` |57| `google_shopping` | `q` | `shopping_results` |58| `google_news` | `q` | `news_results` |59| `google_images` | `q` | `images_results` (не `image_`) |60| `youtube` | **`search_query`** (не `q`) | `video_results` |61| `google_scholar` | `q` | `organic_results` |62| `google_jobs` | `q` | `jobs_results` |63| `google_trends` | `q` | `interest_over_time`, `related_queries`, `related_topics` |64| `google_videos`, `google_local`, `google_patents` | `q` | распечатай `results.keys()` — здесь не зафиксировано |6566## Параметры, которые не угадываются6768| Задача | Параметр |69|---|---|70| Язык / страна выдачи | `hl=en`, `gl=us` |71| Вторая страница | `start=10` (третья — 20) |72| Свежесть: день/неделя/месяц/год | `tbs=qdr:d` / `qdr:w` / `qdr:m` / `qdr:y` |73| Вилка цен в Shopping | `tbs=mr:1,price:1,ppr_min:50` (и/или `ppr_max:200`) |74| Размер картинки | `tbs=isz:l` (`m` средние, `i` иконки) |75| Тип картинки | `tbs=itp:photo` (`clipart`, `lineart`) |76| Публикации от года (Scholar) | `as_ylo=2023` |77| Точка на карте | `ll=@55.75,37.61,15z` — с `@` и `z`-зумом; либо `location=Moscow` |78| Окно Trends | `date="today 12-m"` (`now 1-H`, `now 7-d`, `today 1-m`) + `data_type=TIMESERIES` |7980`tbs` — одна строка: несколько фильтров склеиваются через запятую, второе81присваивание затирает первое.8283## Вложенные поля ответа8485Часть значений лежит глубже, чем кажется по названию:8687- News: `source.name` (не `source`)88- YouTube: `channel.name`, `thumbnail.static`89- Scholar: `publication_info.summary`, `inline_links.cited_by.total`,90 PDF — `resources[0].link` (списка `resources` может не быть вовсе)91- Jobs: `detected_extensions.posted_at`, `detected_extensions.salary`92- Shopping: `price` — строка с валютой, число для сравнения — `extracted_price`93- Maps: `gps_coordinates`, `hours`9495## Гочи9697- Результаты кэшируются ~30 секунд: повтор идентичного запроса вернёт тот же98 снимок. Если нужна свежесть после правки — меняй параметры, а не жми повтор.99- Локаль решает состав выдачи: `gl`/`hl` меняют не только язык подписей, но и100 набор блоков (`answer_box`, «People also ask» появляются не везде).