Верстакфорум практиков
рекламаiprazon: приватные серверные адреса IPv4 и SOCKS5, безлимитный трафик, бесплатный тест до 2 часов
ФорумРазбор ошибок

Пустые ответы без ошибки: где искать

grepwalker
grepwalker
Знаток
сообщений 1330
с мая
8 февраля, 11:37первое сообщение

Обхожу каталог, примерно 60 тысяч страниц. Пятнадцать процентов возвращают код 200 при пустом теле. Исключений скрипт при этом не ловит вообще. Длина строки ноль, разбор молча выдаёт пустую карточку и едет дальше.

Самое обидное, что повтор того же адреса иногда отдаёт полную страницу, иногда снова пустоту. Никакой закономерности по времени я не вижу, пачками тоже не идёт, размазано ровным слоем по всему прогону.

Где вообще искать, когда ошибки нет?

mnogoruk
mnogoruk
Ветеран
сообщений 2050
с мар
15 июля, 14:54#2

Пустое тело при живом двухсотом это почти всегда одно из четырёх. Перечислю в порядке частоты, у меня такая статистика по чужим прогонам.

Первое: сжатие, которое ваш клиент не умеет разжать. Библиотека честно просит brotli в списке кодировок, сайт его даёт, а модуля разжатия в окружении нет. Ошибки не будет, вы получите пустоту или байтовый мусор.

Второе: тело у страницы правда пустое, а содержимое дорисовывается скриптом после загрузки. Тут пустота настоящая и лечится совсем другим.

Третье: вы читаете тело после того, как соединение уже вернули в общий котёл. Такое бывает при потоковом чтении, когда с ответом работают вне блока.

Четвёртое: тихий отказ. Площадка отдаёт 200 с нулевой длиной вместо честного кода, чтобы не подсказывать обходчику, что он попался.

Разводятся эти четыре за одну команду. Снимите заголовки и посмотрите на длину.

grepwalker
grepwalker
Знаток
сообщений 1330
с мая
22 декабря, 17:11#3
mnogoruk: снимите заголовки и посмотрите на длину

Снял. Content-Length там нет вообще, зато есть Transfer-Encoding: chunked и Content-Encoding: br.

Ольга Ветрова
Ольга Ветрова
Участник
сообщений 590
с сен
1 мая, 08:28#4

Вот и приехали, первый пункт из списка. Проверить окончательно можно сравнением сырых байт с разжатыми.

curl -s --raw -H 'Accept-Encoding: br' https://target.example/card/8841 | wc -c
curl -s          -H 'Accept-Encoding: gzip' https://target.example/card/8841 | wc -c

Первая строка покажет тысяч двадцать сырых байт, вторая нормальную страницу. Если так, ваш клиент просит то, что разжать нечем.

skript_kid
skript_kid
Новичок
сообщений 54
с сен, второй сезон
8 октября, 11:45#5

а почему тогда не всегда пусто? половина же приходит нормально

Кирилл Бакин
Кирилл Бакин
Знаток
сообщений 1560
с апр
15 марта, 14:02#6

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

Кстати, это же объясняет, почему повтор иногда помогает: вы попадаете на другой узел раздачи.

tabless
tabless
Участник
сообщений 800
с июл
22 августа, 17:19#7

Добавлю про правильный порядок в таких историях, он экономит часы.

Никогда не верьте объекту ответа, пока не посмотрели сырой обмен. Библиотека показывает вам уже переваренный результат, и весь интерес прячется именно в переваривании: сжатие, кодировка, длина, обрыв нарезки. Разница между «сайт прислал пусто» и «мы не смогли прочитать присланное» видна только на уровне байт.

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

пустые ответы по причинам за сутки прогона
пустые ответы по причинам за сутки прогона

И отдельно: никогда не пишите в списке кодировок то, чего ваш клиент не умеет. Обещали brotli, будьте готовы его разжать.

mnogoruk
mnogoruk
Ветеран
сообщений 2050
с мар
1 января, 08:36#8

Именно. Соврать в этом заголовке проще всего, а последствия самые тихие.

grepwalker
grepwalker
Знаток
сообщений 1330
с мая
8 июня, 11:53#9

Собираю итог, чтобы тема не висела открытой.

Причина была ровно первая. В окружении на сервере не было модуля разжатия brotli, при этом сессия по умолчанию просила его в списке кодировок. Библиотека получала сжатый поток, разжать не могла и отдавала пустую строку без единого предупреждения.

Что помогло: поставил модуль разжатия в окружение и заодно прибил список кодировок гвоздями, теперь прошу только gzip и deflate. Прогнал те же 60 тысяч страниц заново: пустых ответов 214 штук вместо девяти тысяч, и это уже честные страницы, где содержимое дорисовывается скриптом.

Счётчик байт до разжатия и после завёл, как советовал tabless. Стоит три строки, а видно сразу.