У нас есть скрипт, который каждый день просит Google переиндексировать свежие страницы двух сайтов через Search Console — вручную по одному URL это бы никто не тянул, а сайтов и статей достаточно, чтобы запускать это руками было бы отдельной работой. 3 сентября я посмотрел в лог и увидел: за прогон дошло 59 проверок по доставке и 4 отказа «превышена квота», а адреса avitoma, помеченные как приоритетные в gsc_pinned.txt, за сутки не отправились ни разу. Не «отправились с опозданием» — ни разу, вообще.
Индексация Google для нас — в две фазы. Первая идёт через официальный URL Inspection API: скрипт gsc_index_daily.py читает sitemap, спрашивает у Google, в индексе ли страница, и собирает список кандидатов «не в индексе». У этого API квота щедрая, 2000 запросов в сутки на ресурс, тут проблем не было. Вторая фаза — браузер: у кнопки «Запросить индексирование» в интерфейсе Search Console нет публичного API вообще, поэтому по списку кандидатов gsc_click_requests.py кликает по ней сам, через тот же CDP-браузер, что и остальные наши публикаторы. Вот у ручных заявок через кнопку квота уже не 2000, а по практике около 10–12 в сутки, и, судя по нашему логу, она общая на аккаунт Google, а не отдельная на каждый сайт — сервисный аккаунт gsc-indexing@romkola-content.iam... один на avitoma и доставку.
В списке SITES доставка стояла раньше avitoma, а перебор шёл строго по порядку. Пока доставка не исчерпает свой лимит кандидатов, до avitoma очередь не доходила вообще — а у доставки индекс почти полный, ей уже почти нечего запрашивать, основная масса проверок уходила в «уже в индексе» и отказы, но именно они и жрали общую квоту раньше, чем очередь доходила до нового домена.
4 сентября поменял три вещи разом: avitoma переставил в списке первой, дневной лимit кандидатов на сайт вместо одного общего MAX_CANDIDATES = 15 разбил на MAX_CANDIDATES_BY = {"avitoma": 9, "dostavka": 5}, и добавил файл gsc_pinned.txt — адреса из него уходят в начало очереди раньше даже приоритетных городов:
Прогон в тот же день ушёл штатно, пришпиленные адреса avitoma наконец отправились. Проблему счёл закрытой и переключился на другое.
Вечером 4 сентября Роману пришёл алерт с сырым хвостом Playwright: BrowserType.connect_over_cdp: Timeout 30000ms exceeded. Call log: retrieving websocket url from http:. Он не читает по-английски и не обязан разбирать, что такое ws. Причина оказалась банальной: в 12:43 общий браузер грузил обложку поста для TenChat и полминуты не отвечал на новые CDP-подключения. Через минуту всё работало как обычно, но прогон индексации сдался с первой попытки и просто не сделал заявки за сутки. Занятый браузер — это очередь, а не поломка, а мы считали это фатальной ошибкой.
Правка: три попытки с паузой и подъёмом CDP-соединения между ними, и только после третьей — тревога понятным текстом на русском: «не ответил за 30 секунд, обычно занят другой публикацией» вместо websocket-хвоста.
5 сентября, проверяя очередь по новым страницам рубрик avitoma, я обнаружил, что 62 адреса не отправлялись уже две недели, хотя реальных заявок по ним не было ни одной. 32 из них — avitoma, включая как раз новые страницы рубрик, которые мы двумя днями раньше поставили пришпиленными.
Журнал gsc_requested.jsonl пишет строку на каждое событие: requested (заявка ушла), in_index и already_indexed (переиндексация не нужна), но также inspect_fail (не смогли проверить), no_button (кнопку в интерфейсе не нашли — вёрстка Google меняется) и quota_stop (упёрлись в квоту). А load_journal() при построении списка «когда URL трогали последний раз» брал дату из ЛЮБОЙ строки с этим URL, не разбирая статус:
А дальше URL, у которого «последнее касание» было недавно, не попадал в кандидаты следующие RECHECK_DAYS = 14 дней. То есть один отказ по квоте — событие, которое ЗНАЧИТ «мы вообще ничего не отправили» — записывался в журнал так же, как реальная успешная заявка, и на две недели снимал адрес с рассмотрения. Первая правка (порядок сайтов и деление квоты) не поймала эту ошибку, потому что решала другую задачу — кто первый доходит до квоты, а не что журнал делает с отказами. Отказы по квоте были и раньше 4 сентября, только раньше это тонуло в общем шуме и никто не сверял конкретные адреса построчно.
Правка простая — завести множество статусов, которые действительно значат «мы что-то сделали», и фильтровать по нему при чтении журнала:
Оставалось ещё одно: в тот же день, разбирая лог за 4–5 сентября, я увидел подряд шесть строк quota_stop с одной и той же датой в поле date. По одной дате нельзя было понять, это шесть попыток за одну минуту после того, как квота уже кончилась, или шесть попыток размазаны по всему дню — а значит нельзя понять, когда квота Google освобождается и можно пробовать снова. В журнале была только дата, без времени — решение писать date.today().isoformat() без часов принято ещё в момент, когда журнал заводили, и с тех пор так и не пересматривалось. Добавил поле ts с точностью до минуты в обе точки записи (gsc_click_requests.py и gsc_index_daily.py), формат журнала остался обратно совместим — старый код читает date как читал.
С этими правками стало видно реальную картину, а не искажённую бухгалтерией отказов: у доставки индекс почти весь, и гонять по ней проверки каждый день — тратить общую квоту почти впустую. 5 сентября Роман решил поставить доставку на паузу до 12 сентября (сайт вообще не проверяется и не попадает в кандидаты), а весь освободившийся лимит отдать avitoma — её потолок кандидатов за прогон поднял с 9 до 12, чтобы упираться в реальную квоту Google, а не в наш собственный более низкий потолок.
До правок: 3 сентября — 59 проверок доставки, 4 отказа по квоте, 0 заявок по пришпиленным адресам avitoma за сутки. 5 сентября, до фикса журнала — 62 адреса заперты вне очереди из-за отказов, которые никогда не были реальными заявками. После — при том же дневном лимите ручных заявок (по нашим наблюдениям порядка 10–12) весь он уходит на avitoma, кандидатов на прогон 9→12, а из журнала пропали ложные «касания»: адрес с quota_stop возвращается в очередь на следующий же прогон, а не через две недели.
(0)Comments