# Search: поисковая выдача

> Разобранная выдача Google и Яндекса — параметры, метаданные, снимок страницы

Источник: https://docs.parreq.com/search/

`/v1/search` берёт выдачу настоящим браузером и отдаёт её **разобранной**: не
HTML поисковика, а JSON с органикой, рекламой, товарами и остальными секциями.

> **К сведению.**
>   Разница с [`/v1/fetch`](https://docs.parreq.com/fetch) не в адресе, а в задаче. Search знает движки и
>   знает, где у них что лежит. Fetch не знает про содержимое ничего: адрес ваш,
>   разбор ваш.

## Первый запрос

Обязательных параметра два: `q` и `engine`. Умолчания у движка нет намеренно —
иначе запрос молча уходил бы не в тот поисковик, и разбираться, почему выдача
«не та», пришлось бы уже на проде.

```python Python
from parreq import Parreq

client = Parreq("pr_ВАШКЛЮЧ")
res = client.google("coffee machine", gl="us", hl="en")

print(res.metadata["total_ms"], "мс")
print(res.organic[0]["title"], res.organic[0]["link"])
```

```javascript Node

const client = new Parreq({ apiKey: "pr_ВАШКЛЮЧ" });
const res = await client.google({ q: "coffee machine", gl: "us", hl: "en" });

console.log(res.metadata.total_ms, "мс");
console.log(res.organic[0].title, res.organic[0].link);
```

```bash cURL
curl -H "Authorization: Bearer pr_ВАШКЛЮЧ" \
  "https://api.parreq.com/v1/search?q=coffee+machine&engine=google&gl=us&hl=en"
```

Ответ:

```json
{
  "search_metadata": {
    "id": "cdc9e907b324410e",
    "status": "success",
    "engine": "google",
    "requested_url": "https://www.google.com/search?q=coffee+machine&…",
    "final_url": "https://www.google.com/search?q=coffee+machine&…",
    "fetch_ms": 4120,
    "total_ms": 4180,
    "html_size": 412903,
    "detected_location": null,
    "created_at": 1787332891,
    "credits": 3,
    "credits_breakdown": { "search": 2, "engine_google": 1 },
    "credits_left": 748
  },
  "search_parameters": {
    "q": "coffee machine",
    "engine": "google",
    "device": "desktop",
    "gl": "us",
    "hl": "en",
    "page": 1,
    "location": null,
    "domain": null,
    "include": []
  },
  "organic_results": [
    {
      "position": 1,
      "title": "…",
      "link": "https://…",
      "displayed_link": "…",
      "snippet": "…"
    }
  ]
}
```

`search_metadata.id` — номер запроса. По нему же забирается снимок и находится
запрос в истории кабинета.

## Параметры

| параметр | по умолчанию | что делает |
|---|---|---|
| `q` | — | поисковый запрос, обязателен |
| `engine` | — | `google` или `yandex`, обязателен |
| `device` | `desktop` | `desktop`, `desktop_mac`, `mobile`, `mobile_ios`, `tablet` |
| `gl` | `us` | страна: домен движка, часовой пояс, координаты, `Accept-Language` |
| `hl` | `en` | язык интерфейса выдачи |
| `page` | `1` | страница выдачи, до 20 |
| `num` | — | результатов на странице, только Google |
| `location` | — | canonical name для `uule`, только Google: `Berlin,Berlin,Germany` |
| `domain` | по стране | переопределить домен движка: `www.google.by` |
| `include` | — | секции сверх органики, см. [Секции ответа](https://docs.parreq.com/sections) |
| `screenshot` | `false` | снимок страницы выдачи целиком, платно |

> **Внимание.**
>   `gl` задаёт страну **выдачи**, но не адрес, с которого мы приходим. Рекламу
>   Google подбирает по IP, поэтому объявления другого рынка при несовпадении —
>   ожидаемое поведение, а не ошибка разбора.

## Устройство меняет выдачу, а не только вёрстку

`device=mobile` — это не «та же выдача в узкой колонке». У мобильной выдачи
другой состав блоков и другой порядок органики, и сравнивать позиции между
устройствами нельзя: это две разные выдачи.

## Снимок выдачи

`screenshot: true` снимает страницу поисковика целиком — от строки запроса до
пагинации, вместе с рекламой и правой колонкой. Полезен ровно для одного:
убедиться, что выдача та самая, особенно когда клиент спорит о позициях.

```bash
curl -X POST https://api.parreq.com/v1/search \
  -H "Authorization: Bearer pr_ВАШКЛЮЧ" -H 'Content-Type: application/json' \
  -d '{"q":"coffee machine","engine":"google","screenshot":true}'
```

Ссылка приходит в `search_metadata.screenshot_url`, само изображение отдаёт
[`/v1/search/{job_id}/screenshot`](https://docs.parreq.com/api-reference/search-screenshot) — JPEG,
шириной во всю ширину устройства (1920 для `desktop`).

> **Примечание.**
>   Снимок — платная надстройка: 4 кредита, и ключу нужна возможность
>   `screenshot`. Если хранилище не приняло файл, ссылки в ответе не будет, а
>   надстройка вычитается из счёта — [Кредиты и права](https://docs.parreq.com/pricing).

## GET или POST

Одно и то же. GET удобен руками и в браузере, POST — когда параметров много и
не хочется собирать строку запроса. Тело POST — те же имена полей.

## Сколько ждать

| ситуация | время |
|---|---|
| прогретый профиль | 3–10 с |
| профиль поднимается | +2–4 с на старт Chrome |
| поисковик показал капчу | до 2 минут |

Ставьте клиентский таймаут не меньше 180 секунд: столько же держит и сервис,
дальше отвечает `504 timeout`.

## Дальше

**[Секции ответа](https://docs.parreq.com/sections)**
    Полный список секций и форма каждой.

**[Кредиты и права](https://docs.parreq.com/pricing)**
    Цена запроса, движка, секций и снимка.

**[Ошибки](https://docs.parreq.com/errors)**
    Что повторять, а что чинить кодом.

**[Справочник Search](https://docs.parreq.com/api-reference/search)**
    Схема запроса и ответа, примеры на Python и Node.
