Топ комментариев Хабра — сервис, детали реализации, и немного статистики (С#)

    Некоторое время назад страничка «Лучшие комментарии» была удалена с Хабра (подробности здесь: habrahabr.ru/qa/18401).
    Тем не менее, мне бывало интересно туда заглянуть — и ради лулзов, и статьи иногда интересные попадаются из тех, что в ленте упустил. Так что решил я сделать свой небольшой сервис. Надеюсь, администрация не будет против.

    Текущий URL сервиса: habrastats.comyr.com



    Первая «версия» выводила топ комментариев из последних N постов, была написана в LINQPad за два часа и занимала один экран (pastebin). Стало понятно, что «по запросу» это генерить нереально даже для постов за последние сутки (скорость загрузки 1-2 поста в секунду), а значит, надо сделать периодическое обновление. Отсюда пришла мысль крутить сервис на домашней машине (всегда включена) и загружать статичные результаты на бесплатный хостинг.

    Кратко о реализации


    Код: code.google.com/p/habra-stats
    — Windows Service на C# (4.5, VS2012 — новые фичи не используются, можно собрать под 4.0)
    — Парсинг на Regexp (и да, я знаю: You can't parse HTML with regex, но здесь сойдёт)
    — MS SQL Express + Entity Framework (ну очень удобная ORM)
    — XSLT для генерации HTML (вёрстку и css взял у хабра, да простит меня снова администрация)

    Раз в два часа сервис просыпается, парсит страницу habrahabr.ru/posts/collective/new и получает Id самого нового поста, затем в обратном порядке загружает посты, пока дата публикации не достигнет порога (старше 3 дней). Посты парсятся и кладутся в базу.
    Предварительно в базу были загружены все существующие посты (на это ушло двое суток).
    Затем из базы генерятся «отчёты», такие как «лучшие за сутки», «худшие за месяц с картинкой» и т.п. Данные для отчёта — просто набор объектов «Comment», которые сериализуются и трансформируются XSLT. Результаты загружаются по FTP на хостинг.

    Для генерации отчётов и навигации между ними есть небольшая хитрость: каждый из фильтрующих методов (ЗаДень, ЗаНеделю, Лучшие, Худшие и т.д.) помечен атрибутом:
    [CommentReport(Category = "Время" , Name = "За сутки" , CategoryOrder = 0)]

    Через Reflection получаем все сочетания таких методов по категориям, получаем данные из базы и генерируем навигацию. Таким образом, чтобы добавить ещё один «отчёт» (например, «за три дня»), достаточно лишь добавить метод с атрибутом. Слава роботам LINQ и Entity Framework.

    Немного о проблемах и решениях


    Изначально думал обойтись без БД и делать всё как можно проще: хранить сырой HTML на диске, грузить в память и там обрабатывать. Но масштабы бедствия недооценил: 150 тысяч постов в HTML заняли 10 с лишним гигабайт. Даже на SSD время загрузки и парсинга неприемлемо.

    Затем попробовал SQL Compact Edition (in-process база, поддерживает entity framework). Упёрся в лимит 4ГБ на размер файла базы. В тот момент была только одна таблица Comments с дублирующимися (денормализованными) данными. Уже после перехода на SQL Express частично убрал дублирование, добавив таблицу Posts, и удалил комментарии без голосов (которых было около 30%). В результате размер базы сейчас около 2ГБ.

    В процессе парсинга узнал, что опрометчиво использованная RegexOptions.IgnoreCase снижает производительность в несколько раз.

    Немного статистики


    На момент написания статьи в базе:
    90619 постов
    18 комментариев к публикации в среднем (комментариев без голосов в базе нет)
    15 из них с положительным рейтингом

    1676593 комментария всего
    721 комментарий в день

    Среднее количество комментариев по дням недели


    Комментариев в неделю: динамика по времени


    Наконец, ссылки!


    Сайт:
    http://habrastats.comyr.com/

    Код ещё раз: code.google.com/p/habra-stats

    В планах


    RSS с лучшими за предыдущие сутки

    P.S. Предлагайте ещё интересные запросы

    P.P.S. знаменитый комментарий к знаменитому топику про pornolab не отображается, так как автор публикации заблокирован.
    Автор комментария nForce, увидеть комментарий можно здесь: habrahabr.ru/users/nforce/comments/page2
    Share post

    Similar posts

    Comments 45

      –7
      Вы сделали мой день, спасибо!
        +6
        огромное спасибо — лучшие комментарии за день/месяц могут быть лучше чем некоторые топовые посты

        вообще не понимаю зачем это удалили
        +2
        Сравню со своим исследованием habrahabr.ru/post/145045/
        Активность комментариев по дням недели совпала, количество примерно тоже, но у меня не было пика в сентябре 2008
        image
        Самый волнующий комментарий
          +2
          CPU Limit Reached
          You are seeing this page because website has reached CPU usage limit of the server, and it was temporarily disabled.

          Github?
            0
            Печаль, как быстро-то :(
            Спасибо, попробую гитхаб. Надо было сразу резервный вариант готовить…
          +5
          CPU Limit Reached =(
            +1
            UPD: надо обновлять страницу перед постингом комментариев
              +3
              cpu-limit-reached.
              Жаль, не выдерживает хостинг хабраэффекта.
              UPD: надо обновлять страницу перед постингом комментариев
                –13
                Класс, держите нас в курсе!
                  –6
                  >Сайт: habrastats.comyr.com (хостинг выбран первый попавшийся без рекламы с FTP)
                  Для поста в хабре надо было получше подготовиться и купить хостинг, 300 руб жалко? )
                    +2
                    Временно положил сюда: habrastats.host-ed.me
                    Благодаря юзеру tyderh скоро будет хороший хостинг.
                      –2
                      Я отметился в топе =)
                        0
                        У меня одного не получилось на код взглянуть?
                          +3
                          А что именно не получилось, это же гуглокод? Вот ссылка на trunk: code.google.com/p/habra-stats/source/browse/#svn%2Ftrunk
                            +2
                            Посыпаю голову пеплом. Я там ни бум-бум
                              +2
                              Ничего удивительного, GoogleCode такой же прекрасный, как и SVN.
                          +2
                          Отдельное спасибо за ссылку на знаменитый комментарий :)
                            0
                            Еще нужна ссылка на комментарий знаменитого комментария.
                            0
                            Код — жесть. Советую использовать HtmlAgilityPack
                              +1
                              Код, конечно, не идеален, но разве HtmlAgilityPack сделает его сильно проще?
                              Что именно «жесть» помимо парсинга? С удовольствием выслушаю.
                            0
                            Желательно кнопочку для формы «OK», ибо без js не отправляется.

                            Потрясный сервис.
                              0
                              К сожалению, адрес генерится через js, поэтому кнопочка не поможет. Но я постараюсь сделать, чтобы работало без js.
                                0
                                Там же просто ссылки, как я понял. Вместо радио-кнопок может быть было бы удобнее сделать готовый набор ссылок?

                                В IE расплываются поплавки, там лучше использовать display:inline-block, а также сделать clear:both вместо br, или хотя бы прописать <br clear=«all» /> (это перед html_content которая).
                                  0
                                  Сейчас блок навигации один для всех страниц, и он генерирует ссылку через Js, складывая значения из Inputов «za_dvoe_sutok + luchshie + vse + .html».
                                  Да, можно сделать готовый набор ссылок, но для каждой страницы он будет разный, а это усложняет код. Я позже попробую сделать, но, в конце концов, кто сейчас без js?

                                  Спасибо, что заметили косяк в IE. Но побороть не получается :(
                                  div clear both не помогает, как и display:inline-block.
                                  Я в вёрстке не очень копенгаген.
                              +2
                              WTF

                              image
                                0
                                Да там не только первый, но и второй комментарий небезынтересен.
                                  0
                                  Эмм, сделал немного по-другому, но всё равно уползает. Я просто не уверен, как должно быть. Сделать минимальную ширину?
                                • UFO just landed and posted this here
                                    +2
                                    Вместо «длинные» и «короткие» можно смело делить по количеству слов на «умные» и «остроумные».

                                    Такое вот мнение сложилось:)
                                    Читаю, не могу начитаться!
                                      0
                                      Вы зря пропустили сентябрьско-октябрьский пик при аппроксимации на последнем рисунке.
                                        +1
                                        charset=windows-1251
                                        Are you kidding me?
                                          0
                                          Good catch :)
                                          Это, конечно, глупость, там Utf-8, сейчас поправлю заголовок.
                                            0
                                            Вам-то глупость, а мне пришлось ноутбук загружать, ибо мобильный браузер казал кракозябры. А посмотреть уж больно хотелось ;)
                                              0
                                              А что за мобильный браузер?
                                              Opera Mobile, ведроидный и виндофоновый браузеры кажут нормально, я посмотрел ради интереса.
                                          +1
                                          Вон тот мой комментарий (сегодняшний, 12:01 по Москве) не отображается в рейтинге. Хотя он набрал +44.
                                            +1
                                            Это баг, обусловлен тем, что идентификатор поста не связан напрямую с датой публикации (так как пост может долго дежать в черновиках).
                                            Мой алгоритм идёт от максимального Id по убывающей до тех пор, пока дата публикации в пределах последних трёх дней, такие посты загружаются и обрабатываются.
                                            Тот пост имеет Id 155429, следующий за ним валидный (то есть предыдущий в обратном порядке) 155431, опубликован 19 октября, то есть алгоритм просто не добрался до этого поста.

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

                                            Спасибо за багрепорт.
                                              0
                                              Пожалуйста.
                                                0
                                                Готово, ваш комментарий отображается.
                                                Сделал 6 дней вместо 3. Время загрузки 25 минут, пока приемлемо.
                                            0
                                            Добавлена поддержка GeekTimes и MegaMozg. Рейтинг комментариев по всем сайтам общий.
                                              0
                                              Что-то перестал обновляться сабж, еще 27 октября.
                                                +1
                                                Хостинг сдох. У них утекла база паролей: thehackernews.com/2015/10/free-web-hosting-hacking.html
                                                Сначала просто заблокировали панель управления, потом включили, но FTP до сих пор не работает.

                                                Может, найду время, перетащу куда-нибудь ещё. Хотя популярность хабрахабра сильно упала. А вместе с ней и посещаемость сервиса. В последнее время едва 10 чел в сутки. Так что может просто прикрою лавочку. Статей интересных почти нет, как и комментариев к ним.

                                            Only users with full accounts can post comments. Log in, please.