Comments 29
Первый комментарий!
Четыре минуты и первая позиция - вы только что собрали лучший из возможных раскладов по моей же статье. Осталось выяснить, работает ли она.
собрали лучший из возможных (и рискованных) раскладов
Чуть дополнил.
Проверил, любопытно вышло: риск-то как раз не подтверждается. Первые в треде короткие однострочники (меньше 60 знаков, тексты я не хранил, так что мерил длиной) набирают в среднем 4.38 плюса против 3.59 у развернутых, и в минусе оба варианта одинаково редко, около 4%.
А вот в общей массе, не на первой позиции, короткие ощутимо хуже длинных: 38.7% в плюсе против 47.1%. То есть однострочник наказывается везде, кроме одного места - самого начала треда. Похоже, позиция вытягивает даже “Первый комментарий!”, и в этом есть своя жестокая справедливость. Видимо, многие из нас ещё помнят олбанскей.
А где в дев-панели глядеть, куда смотрит фронт в API? Есть мысль запилить сборщик ссылок на статьи, которые ещё не видел, пока в отпуске и без доступа в сеть. Напоролся на это в этот отпуск, блин. Две недели в сети не было - и на тебе. Уехал 24 июля, а долистать ленту постов по возвращению смог только до 28 июля. Всё, что было ранее - привет. И техподдержка сказала, что ничем помочь не может. Даже календаря постов нет. Что странно. Так что "помоги себе сам".
DevTools -> вкладка Network -> фильтр Fetch/XHR, дальше просто листаете ленту и смотрите, что уходит на habr.com/kek/v2/. Всё, что видно на странице, там же и лежит в JSON.
Конкретно под вашу задачу: GET https://habr.com/kek/v2/articles/?fl=ru&hl=ru&sort=date&period=monthly&page=N
В ответе publicationRefs - id, заголовок, время, статистика; pagesCount - сколько всего страниц. Два подводных камня, оба стоили мне вечера: без period прилетает 422, а с дефолтным curl-овским User-Agent Хабр не ругается, а молча отдаёт урезанный ответ - ставьте браузерный UA.
Плохая новость: pagesCount упирается в 50, это 1000 статей за проход, дальше 400. period=monthly сейчас достаёт до 15 июля - ваш отпуск бы закрыл впритык, но окно едет каждый день, так что архив за прошлое уже не собрать.
Хорошая: на будущее это ровно то, что вам нужно. Раз в пару дней дёргать period=weekly (32 страницы), складывать id в локальный файл - и никакого «долистал только до 28-го». Заготовка есть в гисте из статьи, collect_habr.py делает ровно этот постраничный обход с паузой 0.6-0.7 с между запросами: https://gist.github.com/k41n/973a7593738393e21ce7165be2e9c8f3
О! Ништяк. Сердечно кланяюсь за помощь. Не ожидал от дрг Мрзд такого быстрого ответа в вашем лице. :) Позавчера проблема, сегодня - практически решение. Осталось только хостинг для этого дела подобрать. Селф-хостинг как-то стрёмно оставлять на две недели.
Дык, GitHub Actions - халява же. Репа со скриптом, workflow по расписанию (on: schedule, cron), скрипт складывает свежие id в JSON и коммитит его обратно в репу. Из отпуска открываете файл прямо в вебе с телефона, когда сеть появится. Для публичного репозитория это бесплатно, а лимитов хватает с запасом: пара минут раз в день.
Один попадос есть: GitHub отключает scheduled workflows в репке, где 60 дней не было активности. Но раз наш workflow сам коммитит результат, активность есть каждый день, и отключать его не за что.
Я часто так делаю для целей самообновляющихся файликов в вебе, тащемта
Ок. Надо будет при случае покурить всё это.
Про девтулз не впитал только. Я на ФФ сижу и за Каспом. Он мне по F12 в разделе XHR только общую инфу показывает.
Ссылку из моего прошлого комментария просто вставьте в адресную строку - у ФФ вроде есть встроенный просмотрщик JSON, откроется деревом, с поиском и кнопкой “Необработанные данные”. Меняете page=1 на page=2 и смотрите, что приходит. Девтулз нужен только чтобы подсмотреть незнакомую ручку, а я уже всё спалил.
Всё это ок. А если API изменится, чего делать? Вот перейдут на v3, к примеру, и?
У вас тоже всё сломается, и никто не предупредит. API недокументированный, никаких гарантий обратной совместимости у нас с вами нет.
Но без паники! Первая: это не публичное API для сторонних разработчиков, а внутреннее для собственного фронта, и меняется оно тогда, когда переписывают фронт. v2 живет годами, я на него натыкался еще до того, как взялся за статью. Вторая: при переезде на v3 старую версию обычно какое-то время не выключают, потому что на нее завязаны и мобильные приложения, и закешированный у людей фронт.
Практически нужно одно - чтобы поломка была громкой, а не тихой. Я бы сделал, если бы это была не поделка для себя, а кровавый энтерпрайз, проверку, что в ответе действительно есть publicationRefs и он непустой, а если нет - падать с шумом. GitHub Actions на упавший workflow сам пришлет письмо, и вы узнаете о поломке в тот же день, а не через месяц пустого файла. Чинится это потом теми же пятью минутами в девтулзах: открыли ленту, посмотрели, куда фронт ходит теперь, поправили URL.
Скрытый текст

И ещё (надеюсь) последний вопрос: json отдельными файлами сохраняется или обновляется каждый раз один и тот же файл?
Один файл, и пусть он копится. Словарь вида id статьи - заголовок, ссылка, дата, и на каждом запуске вы просто дописываете в него то, чего там еще нет.
Отдельные файлы по датам смысла не имеют ровно потому, что вы уже в гите: историю за вас ведет он. Более того, это и есть главный бонус такой схемы - в диффе очередного коммита лежит ровно список того, что появилось с прошлого запуска. Из отпуска можно даже не открывать сам файл, достаточно пролистать коммиты за две недели, каждый со своим списком новинок.
Единственное, что стоит сделать сразу: сортируйте ключи при записи (json.dump с sort_keys=True, indent=2). Иначе питон будет тасовать порядок, и каждый дифф превратится в шрапнельные правки вместо аккуратного списка
Eсли я правильно понял, вашу проблему мог бы решить self-hosted rss-сервер (есть и арендуемые сервисы, но я лично не любитель)
Примеры feed-ов habr-а:
https://habr.com/ru/rss/news
https://habr.com/ru/rss/users/k41n/publications/articles/?fl=ru
Спасибо, полез проверять и заодно померил, насколько этого хватает. Результат интереснее, чем я ожидал.
Потолок у всех фидов Хабра одинаковый и жесткий - 41 запись. Пагинации нет вообще: ?page=2 и /page2/ отдают тот же ответ байт в байт. А вот глубина этого окна зависит только от того, сколько в фид сыплется:
общая свежая лента - около 4.5 часов новости - около 15 часов top/daily - сутки, top/weekly - неделя, top/monthly - до 20 июля хаб programming - 4 дня хаб cpp - с 24 июля хаб ruby - аж с апреля 2024
Отсюда и ответ на исходный вопрос. Общая лента для двухнедельного отпуска бесполезна, за 4 часа окно уезжает. А вот подписка на конкретные хабы работает как надо, и никакого сервера для этого не надо: узкий хаб держит месяцы, широкий - несколько дней. Плюс top/monthly для общей картины, если не хочется совсем ничего пропустить из громкого.
Так что для чтения RSS явно удобнее моей возни с JSON. JSON остается нужен, только если хочется полную ленту без отбора по хабам и топам.
Но без GHA или своей арендованной железки всё равно не обойтись...
Да, я это сбросил именно для чтения как решение проблемы пропущенных во время отпуска постов: RSS-лента обновляется RSS-сервером по расписанию, поэтому попадёт туда вообще всё. Для аналитики это бесполезно, т.к. у всех RSS-лент есть лимиты (обычно это 50 item-ов).
Из плюсов своего сервера, кроме regex фильтров, - синхронизация прочитанного между устройствами.
Согласен, так и есть: с сервером, который копит у себя, лимит перестает что-либо значить. Мое замечание работало только потому что исконный спрашиватель писал такое: "Селф-хостинг как-то стрёмно оставлять на две недели." Есть железка или VPS - ваш вариант однозначно лучше, синхронизация прочитанного и regex-фильтры в самодельном скрипте не появятся никогда. Не готовы - остаются хабовые фиды, которые за счет низкого трафика держат окно неделями, или GitHub Actions в роли того же накопителя, только бесплатного и чужого.
Про бесполезность для аналитики полностью подписываюсь (хотя и не потому, что лимиты): там нужны score и время каждого комментария, а в RSS этого нет и быть не должно.
Без своего сервера есть feedly, inoreader, публичные инстансы freshrss, newsblur, - тысячи их, есть и бесплатные.
А взаимосвязь между авторами комментаторов и автором статей учитывалась? А то прогревы статей типа "Мужики, я 15 лет в айти" соберут плюсы просто из-за своей специфики.
Нет, как и качество комментариев. Вопрос стоит как: при равном качестве комментариев и одинаково популярном авторе комментария куда выгоднее его поставить? Понятное дело, что если придёт на Хабр Карпатый какой-нибудь, то его любой коммент наберёт лайков. Так же с качеством: коммент может завируситься, например. Но это выбросы.
Я решал задачу для себя. Я - тот, кто я есть и писать комменты умею так, как умею. На это повлиять я не могу. Могу повлиять лишь на то куда и когда писать.
Взаимосвязь не учитывал, но ваш вопрос заставил пойти и посчитать. Смотрел пары “автор статьи - комментатор”, которые за неделю встретились больше одного раза.
Таких пар 11 из 2481, это 40 комментариев из 4399, меньше процента. И живут они хуже среднего: в плюсе 40% против 46.4%, средний score 0.75 против 1.84. Постоянных групп поддержки, которые ходят за автором из треда в тред, в недельном срезе просто нет в товарных количествах.
Две честные оговорки. Голоса анонимны, так что кружок, который молча плюсует и не пишет, этим способом не поймать никак. И в моделях контроли на уровне статьи - просмотры, рейтинг, размер треда, - но не поправка на каждую конкретную статью. Специфика жанра “мужики, я 15 лет в айти” учтена ровно настолько, насколько она видна в этих трёх числах.
Комментируй статьи моложе 12 часов. Старше суток - лотерея против тебя.
Потому что читатели статьи к ней уже не возвращаются. Прочитал, в закладки не добавил, забыл, конец истории.
Но между теми кого тема серьезно заинтересовала, диалог может продолжаться еще долго. Причем отсутствие посторонних может быть даже плюсом (меньше вероятность что у кого-то из “прохожих” подгорит от комментария,и он поставит минус в карму)
насколько статья вообще живая: размер треда, просмотры, рейтинг
Если просмотров много, то комментировать уже поздно. Читатель статьи не вернется чтобы почитать комментарии. Зритель уехал, клоуны остались.
В 2008 году, когда я ещё только его зарегистрировал, было принято фармить сначала комментариями карму и только потом писать статьи
Это было очень логично. Сначала тренируйся на кошках, смотри реакцию, делай выводы. “Комментарии” служили “лягушатником” для начинающих авторов. Теперь это больше похоже на “пикабушник” для выплескивания эмоций.
Целься в первую десятку комментариев, лучше - в тройку.
Это означает стрелять быстро. Но в спешке можно попасть себе в ногу.
Иногда перед комментарием статью все же требуется прочитать. Иначе можно ляпнуть такое, что карма покраснеет (от стыда).
Но чтение статьи и обдумывание комментария отнимает время, и попасть в тройку уже сложно. Пока бегаешь за ружьем, чистишь его и заряжаешь, все уже закончено. Слон убежал, поляна засыпана мусором и мертвыми туристами.
Про просмотры не соглашусь, тут мухи с котлетами склеились. Просмотры это не "статья остыла", а "статью много читают", и на свежих комментариях это прям видно: среди тех, что написаны в первые три часа, у статей выше медианы по просмотрам средний урожай 8.3 плюса и 78% в плюсе, у статей ниже медианы - 1.4 плюса и 54%. Одинаковая свежесть, разница почти шестикратная. В регрессии то же самое: log(просмотров) даёт +0.165 при t=9.4, и это уже с учётом лага.
Так что правило не "беги от популярных", а "беги от несвежих, беги к популярным". Пятый комментарий под будущим хитом лучше первого под статьёй-невидимкой.
Со всем остальным согласен, и особенно с последним. Скорость против качества это реальный размен, и мои данные его не разрешают: качество комментария я не мерил вообще. Единственный честный выход из него не "печатай быстрее", а "комментируй то, в чём и так разбираешься". Тогда чтение статьи занимает пять минут, а не полчаса, и в первую десятку успеваешь без стрельбы по ногам.
Про "лягушатник" точное наблюдение. Похоже, эта функция отвалилась вместе с обязательным фармом кармы: тренироваться теперь негде, а сразу писать статью страшно. Ну мне, например, после возврата, страшно было...
Добавлю. Еще важен уровень комментария в диалоге. Коммент который находится на первом уровне, набирает больше лайков, чем коммент отвечающий на другой коммент.
Проверил на данных - вы правы, и этого фактора в статье нет, спасибо. Сырые цифры по глубине вложенности:
уровень 0 (корневой): 55.6% в плюсе, средний 2.71 уровень 1: 48.9%, 2.03 уровень 2: 43.5%, 1.34 уровень 3: 38.6%, 1.18 уровень 4 и глубже: 33.7%, 0.83
Но тут та же ловушка, что и с временем суток, поэтому сразу проверил на свежих комментариях, моложе трех часов: 5.36 у корневых, 4.29 на первом уровне, 3.47 на втором. Разрыв остается, но заметно ужимается - значит бОльшая часть сырой разницы это опять свежесть и позиция, которые прячутся за глубиной. Ответ по определению приходит позже того, на что отвечает.
Механика, судя по всему, простая: корневой комментарий видят все, кто открыл статью, а ответ на пятом уровне - только те, кто дочитал ветку. Читателей меньше, голосов меньше.
Да, конечно, удаленность от начала комментариев влияет гораздо больше чем уровень вложенности. Но вот что характерно, когда я пишу этот комментарий, у всех комментов первого уровня стоят лайки, и только у 3 из 12 следующих уровней есть лайки.
Когда комментировать на Хабре: я разобрал 4404 комментария