Парсинг картинок из выдачи: фильтры Яндекса, Google и Bing

· парсинг · картинки

Поиск по картинкам — отдельная выдача со своими правилами: другая разметка, другой размер страницы, другая пагинация и свой набор фильтров у каждого поисковика. Собирают её ради разного: проверить, откуда расходятся ваши изображения, найти оригинал по теме, набрать обучающую выборку, посмотреть, чьи картинки поисковик считает подходящими под запрос.

Ниже — что в трёх поисковиках устроено одинаково (и потому вынесено в общие параметры), а что у каждого своё и задаётся его собственными фильтрами. Методы: /api/yandex/images, /api/google/images и /api/bing/images.

Одна форма ответа на три поисковика

Карточку картинки все трое описывают одними и теми же вещами, но по-разному: где-то страница-источник отдельным полем, где-то только её домен, где-то размеры превью, а где-то их нет. Мы приводим всё это к одному виду, поэтому разбор пишется один раз:


{
    "url": "https://i.ytimg.com/vi/Fdier2UCgo0/maxresdefault.jpg",
    "title": "Cats Try Not To Laugh 17 - YouTube",
    "domain": "youtube.com",
    "sourceUrl": "https://www.youtube.com/watch?v=Fdier2UCgo0",
    "thumbnail": "https://avatars.mds.yandex.net/i?id=a5d639a87b2590663763dbdc42ee0367",
    "width": 1280,
    "height": 720,
    "thumbnailWidth": 480,
    "thumbnailHeight": 270,
    "bytes": 78219
}

Первые четыре поля есть всегда и у всех трёх. Дальше начинаются различия, и они оформлены отсутствием поля, а не пустым значением: bytes и размеры превью называет только Яндекс, а Bing не всегда называет размер оригинала. Ноль вместо неизвестной ширины читался бы как картинка нулевого размера, поэтому в таком случае поля просто нет.

Два поля стоит различать с самого начала. url — это адрес самого файла на сайте-источнике, его качают. sourceUrl — страница, на которой картинка стоит, на неё ссылаются. А domain — домен именно страницы-источника, а не CDN, откуда файл раздаётся: по нему отвечают на вопрос «кто это опубликовал», и он часто не совпадает с хостом в url.

thumbnail — превью на серверах самого поисковика. Оно живёт дольше оригинала и отдаётся кому угодно, тогда как оригинал нередко закрыт от хотлинка: если картинки нужно показывать у себя, брать стоит именно превью. У Google есть особенность — первые карточки страницы приезжают превью прямо байтами (data:image/png;base64,…), и на них уходит заметная часть веса ответа.

Общие фильтры: одно имя на три поисковика

Размер, ориентация, цвет, тип, формат файла, свежесть и сайт есть в том или ином виде у всех трёх. Задаются они общими именами, одинаково для любого поисковика:

https://jsonseo.ru/api/yandex/images?key=ВАШ_КЛЮЧ&text=котики&size=large&orientation=horizontal&format=png
https://jsonseo.ru/api/google/images?key=ВАШ_КЛЮЧ&q=котики&size=large&orientation=horizontal&format=png
https://jsonseo.ru/api/bing/images?key=ВАШ_КЛЮЧ&q=котики&size=large&orientation=horizontal&color=mono

Один и тот же orientation=vertical уходит Яндексу как iorient=vertical, Google — как tbs=iar:t, Bing — как qft=+filterui:aspect-tall. Полный список значений — в документации.

Чего у поисковика нет — то ошибка, а не тишина

Совпадение неполное, и это главное, что стоит знать про общие фильтры. Bing не отбирает картинки по формату файла (кроме gif — он у него выбирается типом «анимированный GIF»); у Яндекса нет ни розового с коричневым в цветах, ни прозрачного фона в типах, а окна свежести у него свои — трое суток, неделя, две недели, месяц, и ничего шире месяца.

В таких случаях запрос возвращает 422 с указанием, чем заменить это значение у нужного поисковика. Проверка происходит до обращения к поисковику, поэтому отказ ничего не стоит.

Отказ здесь полезнее тишины. Сами поисковики на непонятое значение фильтра не ругаются: они молча его выбрасывают и отдают обычную нефильтрованную страницу с честным 200. Снаружи она неотличима от отфильтрованной — та же сотня карточек, тот же вид, — а стоит столько же. Запрос с опечаткой вроде color=rd вернул бы все цвета без единого признака, что фильтр не сработал.

Два фильтра в одну ручку

Ещё один случай, когда приходит ошибка. У Яндекса анимация живёт не в типе изображения, а в его формате — itype=gifan. Значит type=animated вместе с format=png просят у него взаимоисключающего, и такой запрос отклоняется: по ответу было бы не видно, какой из двух фильтров отброшен. То же у Bing с type=photo&format=gif и у Google, когда общий фильтр и своя запись tbs метят в одно место.

Расширенные фильтры: у каждого свои

Всё, чего в общем списке нет, задаётся родными параметрами поисковика. Они перечислены ниже и уезжают в поисковик как есть, без перевода. А то, чего нет и в этих списках — например фильтр, который поисковик добавит завтра, — задаётся сырой строкой: tbs у Google и qft у Bing принимают любые записи и складываются с остальным.

Яндекс

Параметр Значения
isize large, medium, small; либо wallpaper — только вместе с wp
wp размер экрана для обоев: wh16x9_1920x1080
type photo, clipart, lineart, face, demotivator
icolor color, gray; либо red, orange, yellow, cyan, green, blue, violet, white, black
itype jpg, png, gifan
recent 3D, 7D, 14D, 1M
site домен; поддомены попадают тоже — wikipedia.org вернёт и ru., и en.

Три вещи, на которых легко обжечься. Анимация называется gifan, а не gif. isize=wallpaper без wp (и наоборот) Яндекс не отвергает — он просто ничего не делает, поэтому пара принимается только целиком. И у recent ровно четыре значения: 1D, 30D, 2M, 12H и week выглядят разумно, но не работают — поиск расширяется на всё время.

Страница у Яндекса — 20 картинок, и параметром это не меняется: numdoc, rpp и прочее на размер не влияют. Глубина — 20 страниц, то есть 400 картинок на запрос.

Google

Все фильтры вертикали Google складывает в один параметр tbs через запятую; порядок частей значения не имеет.

Запись Что делает
isz:l, isz:m, isz:i большие, средние, значки
isz:lt,islt:4mp не меньше N мегапикселей: 2mp…70mp, а также qsvga, vga, svga, xga
isz:ex,iszw:1024,iszh:768 точный размер — просьба, а не гарантия
iar:t, xt, s, w, xw вертикальные, панорама, квадрат, горизонтальные, панорама
ic:color, ic:gray, ic:trans полноцветные, чёрно-белые, с прозрачностью
ic:specific,isc:red конкретный цвет: 12 значений, включая pink и brown
itp:face, photo, clipart, lineart, animated тип изображения
ift:jpg, png, gif, webp, bmp, svg, ico, craw формат файла — в интерфейсе Google этого фильтра нет, но он работает
sur:cl, sur:ol лицензии Creative Commons; коммерческие и другие
qdr:d, w, m, y за сутки, неделю, месяц, год
cdr:1,cd_min:1/31/2025,cd_max:12/31/2025 произвольный период, даты в формате M/D/YYYY

Старые значения прав sur:f, sur:fc и sur:fmc больше не работают — их место заняли cl и ol.

Те же фильтры Google принимает и полями формы расширенного поиска — imgsz, imgar, imgtype, imgcolor, as_filetype. Они работают наравне с записями tbs, так что использовать можно любую из двух форм.

Страница у Google — сто картинок, и это заметно меняет арифметику: одна страница /api/google/images стоит столько же, сколько страница Яндекса на 20 карточек. num=20 размер не двигает. Смещение здесь считается сотнями: start должен быть кратен 100.

Bing

Bing описывает все фильтры вертикали одним параметром qft — цепочкой токенов +filterui:ручка-значение. Мы собираем его сами, но сырой qft тоже принимается и складывается с остальным.

Параметр Значения
imagesize small, medium, large, wallpaper; либо 1920x1080 — не меньше этих сторон
aspect square, wide, tall
imagetype photo, clipart, linedrawing, animatedgif, transparent
people face (только лица), portrait (голова и плечи)
license any, public, share, sharecommercially, modify, modifycommercially
qft сырая цепочка токенов — для фильтра, которого здесь ещё нет

Своего у Bing два: минимальные стороны в размере (imagesize=1920x1080 — «не меньше этих сторон», более крупные тоже попадут) и портрет — голова и плечи отдельно от просто лиц. Лицензия и прозрачный фон, вопреки распространённому мнению, у Bing не эксклюзивны: у Google это tbs=sur:cl и tbs=ic:trans, только записаны иначе. Чего у Bing действительно нет — отбора по сайту и по формату файла.

И есть ручка, которой нет ни у кого: count — сколько карточек просить на страницу, до 35. Это самый дешёвый параметр здесь, потому что цена считается страницами: count=35&pages=5 даёт около 174 картинок за пять страниц вместо разнобоя, который Bing выдаёт по своему усмотрению.

Пагинация: страница у всех своя

pages и page работают как в обычной выдаче, но «страница» здесь у каждого своего размера:

Соседние страницы у поисковиков слегка пересекаются, поэтому повторы в пределах одного запроса отбрасываются, и результатов может оказаться меньше, чем pages × размер страницы. Как и в обычной выдаче, несколько страниц лучше просить одним запросом через pages, а не отдельными запросами со смещением — подробности в статье про параметр page.

Чем вертикаль картинок сложнее обычной выдачи

Общие беды парсинга — капчи, блокировки, постоянно меняющаяся вёрстка — разобраны в статье про парсер выдачи Яндекса. У картинок к ним добавляются свои, и неприятны они тем, что почти все молчаливые: сбор не падает с ошибкой, он продолжает отдавать правдоподобный ответ.

Пустой ответ не означает «ничего не нашлось». Поисковики пускают в вертикаль далеко не всех, и отказ приходит не ошибкой, а страницей — просто без картинок. Отличить «по запросу ничего нет» от «запрос заблокирован» по такому ответу нельзя, и сбор, который этого не различает, спокойно записывает пустоту как честный результат.

Порядок теряется незаметно. Ранжирование в выдаче картинок задаётся не тем же способом, что порядок карточек на странице, и разъезжается легко. Снаружи это не видно вовсе: те же двадцать картинок, тот же вид — только позиции перепутаны. Для мониторинга это худший вид поломки, потому что данные выглядят исправными.

Размер страницы не задаётся параметром. Сколько картинок отдаст поисковик, решает он сам, и число меняется от запроса к запросу. Расчёт «страниц столько-то, значит результатов столько-то» перестаёт сходиться, а пагинация, построенная на постоянном шаге, начинает пропускать или дублировать целые куски выдачи.

Фильтры исчезают молча. Уже упомянутое, но повторить стоит: неизвестное значение фильтра не вызывает ошибки ни у одного из трёх. Оно просто пропадает, а выдача приезжает полной — та же сотня карточек, тот же вид, и никакого признака, что искали совсем не то.

В /api/*/images все эти ловушки уже закрыты: блокировка не приходит под видом пустой выдачи, порядок результатов сохраняется, а общий фильтр, которого у поисковика нет, возвращает ошибку до обращения к нему — за неотфильтрованную выдачу платить не придётся. Родные записи tbs и qft при этом уходят как есть: что они значат, решает поисковик.

И последнее, что стоит помнить про любые фильтры картинок: фильтр сужает, но не гарантирует. Чем больше фильтров сложено вместе, тем чаще среди результатов попадается что-то, под них не подходящее. Классификацию делает поисковик, и расширение в адресе никогда не было доказательством формата. Если нужна гарантия — фильтруйте и по результатам тоже.


Читайте дальше

Страны и языки в Google: параметры gl и hl

Москва в uule и gl=by дают белорусскую выдачу, а незнакомый hl Google молча превращает в английский. Разбираем, кто за что отвечает, и даём полные списки — те же, по которым API проверяет запросы.

Страны, рынки и языки в Bing: mkt, cc и setlang

Можно запросить Катар и получить московскую выдачу. Разбираем, кто из трёх параметров за что отвечает, и даём полные списки — те же, по которым API проверяет запросы.