- PVSM.RU - https://www.pvsm.ru -
Полагаю, все мы однажды искали себе жилье. Кто-то — в собственность, большинство, вероятно, в аренду. Все, кто хоть раз пытался найти реальные предложения на досках объявлений, знают — это нереально. Такого количества спама нет, пожалуй, ни в одной другой сфере. После того, как окунешься в этот ад, обычно руки начинают чесаться применить свою IT-шность на благо ближнему. Результатом для меня стал проект Sobnik, о котором я и хочу рассказать.
Sobnik — это плагин для Chrome, который помечает посредников на досках объявлений. Пока работает только с Avito.ru [1], в ближайшем будущем я добавлю Irr.ru [2] и другие крупные доски. Всех, кто сидит на чемоданах и кому не терпится попробовать, прошу в Google Web Store [3]. Под катом я расскажу о технической стороне проекта, о его перспективах и о моих наблюдениях за противником посредниками. Любители критиковать чужой JS-код также велкам, исходник клиентской части плагина доступен на github [4].
Для любителей точности уточняю: формально, Sobnik это «расширение», а не плагин, но уж больно я к последнему термину привык.
«Польза обществу», надеюсь, очевидна, поэтому сразу перейду к вопросу «зачем это лично мне». Столкнувшись в последний раз с поиском жилья, наплевавшись на спам, которым заполнен Интернет, насмотревшись на изобретательных риэлторов, я ощутил прямо таки укол совести. Как никак корабли уже бороздят просторы 21-го века, неужели мы, Программисты, не способны справиться с жалкими спамерами?
Поразмыслив, я рискнул предположить, что способны. Просмотра нескольких сотен объявлений было достаточно, чтобы понять — посредников выявить легко. Либо по содержанию объявления, слишком подозрительному или очевидно агентскому, либо по наличию множества предложений с одним и тем же номером телефона. Оставалось выбрать технологии, на основе которых эту идею можно было проверить — объявления нужно было распарсить, куда-то сохранить, и проанализировать. В качестве парсера я выбрал Google Chrome — для доступа ко всей нужной информации на досках объявлений требуется полноценный браузерный движок с работающим JavaScript-ом. Для серверных дел решил попробовать Go и MongoDB. Все три вещи были для меня в новинку, так что это была отличная возможность расширить горизонты и освоить что-то новое. В итоге получился Sobnik.
На первый взгляд — довольно просто. Доступным и достоверным индикатором служит номер телефона, на который дано множество объявлений. Ведь не станет же агент покупать под каждое объявление новую сим-карту! Кроме того, некоторые объявления содержат прямые упоминания что автор риэлтор и хочет комиссию. В теории оно конечно просто, на практике пришлось решать множество мелких вопросов:
Использование этих приемов позволяет автоматически выявлять большую часть посредников. Вот так выглядит Авито во время активности спамеров (красные и зеленые кружочки — результат работы Sobnik-а):

Плагин написан на JavaScript, поскольку функционала API Хрома [6] вполне достаточно для поставленных целей. Единственная сложность была с получением изображения номера телефона. Дело в том, что Avito отдает его только для запросов с правильным Referer-ом. В браузере подделать этот заголовок возможности нет, а получить данные изображения, загруженного страницей Avito, не дает Cross-Origin Policy [7]. Оказалось, что эту защиту легко обойти — я сохраняю страницу в формате MHTML [8] через соответствующий API [9], а затем из полученной строки вырезаю [10] нужный мне кусок, содержащий изображение в base64-кодировке. Таким же методом получаю доступ и к фотографиям квартир.
Далее, информация отправляется на сервер, где работает программа на Go. На самом деле две программы — все запросы выполняются асинхронно, одна программа пишет все запросы в очередь, вторая программа эти запросы обрабатывает. В клиентскую часть встроена логика по замедлению потока обращений к серверу в случае, если тот не успевает выполнять запросы вовремя. Такой подход позволит сгладить скачки нагрузки (очень надеюсь, что сегодня они возникнут). Данные хранятся в MongoDB.
Все это хозяйство я разместил на Amazon AWS (еще одна штука, которую хотел попробовать). Пока «Free Tier» вполне хватает, так что за не плачу.
Серверный API доступен публично, никакой авторизации. Подозреваю, что найдутся желающие побаловаться и напакостить, так что в ближайших планах — внедрить кое-какую защиту. В конечном счете почти наверняка приду к регистрации пользователей плагина, но пока не хочу добавлять лишних барьеров для желающих попробовать.
Исходный текст плагина открыт [4]. Во-первых, все равно его не скроешь. Во-вторых, сразу видно какую именно информацию собирает плагин, так что у понимающих людей не будет вопросов касаемо приватности. Ну и, наконец, вдруг однажды появятся энтузиасты, желающие поучаствовать в разработке.
Централизованного краулера для сбора данных нет. Во-первых, Авито отрубает IP-шники, которые открывают порядка пары сотен страниц в час. Во-вторых, я надеюсь, что когда пользователей станет много, получится распределенный краулер — каждый откроет по паре объявлений, вот и наполнилась база. Однако, пока активных пользователей нет — база пуста. Основная польза от плагина в том, что не надо открывать агентские объявления, а если в базе пусто — то открывать придется все подряд. В общем, чтобы придать системе хоть какое-то ускорение, я сделал еще один плагин для внутреннего использования, который тихонько, примерно по страничке в минуту, сканирует на Авито предложения о сдаче квартир в Москве. Успевать за спамерами в пиковые часы не получается, но все же у вас, уважаемый читатель, будет возможность оценить как работает Sobnik: установили, открывайте на Авито вышеуказанный раздел [12] и наслаждайтесь. Буду рад предложениям о том, как наладить сканирование Авито в более серьезных масштабах. Желающим могу выдать плагин для краулинга, если вдруг хотите помочь проекту или посканировать другой город или раздел.
Запустив сканирование аренды в Москве, я сделал несколько полезных наблюдений. Все они довольно логичны и кажутся очевидными, однако Sobnik позволил их наглядно проверить и подтвердить:
Этот список, в целом, позволяет глазами отфильтровать почти весь мусор, так что если вам лень ставить Sobnik — пользуйтесь.
Disclaimer: Я ни сколько не против риэлторов. Для них на Авито если специальная галочка, ставишь её — и всем сразу понятно что ты — агент. И конечно я в курсе, что во многих случаях агент просто необходим. Sobnik борется лишь с теми, кто спамит и пытается вас обмануть.
Развивать проект я планирую в двух направлениях:
Теоретически, когда будет активно сканироваться много досок, Sobnik сможет находить исходное объявление собственника по его копиям, опубликованным агентами на других досках. Удастся ли достигнуть этих высот покажет время, и конечно же ваши ценные комментарии.
Публиковать собираемую базу объявлений я не планирую, слишком уж нагло было бы красть и распространять эту информацию. Однако, раз уж финансовый план Авито не позволяет им самим фильтровать спамеров, этим займется Sobnik.
Вашим пожеланиям и предложениям буду очень рад.
Автор: cerber
Источник [13]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/70181
Ссылки в тексте:
[1] Avito.ru: http://www.avito.ru
[2] Irr.ru: http://irr.ru
[3] Google Web Store: https://chrome.google.com/webstore/detail/sobnik-%D1%84%D0%B8%D0%BB%D1%8C%D1%82%D1%80%D1%83%D0%B5%D1%82-%D1%80%D0%B8%D0%B5%D0%BB%D1%82%D0%BE%D1%80%D0%BE/ecpajfcndndkccbagpemjgdjfoaackac
[4] github: https://github.com/sobnik/sobnik.chrome
[5] OCR: http://en.wikipedia.org/wiki/Optical_character_recognition
[6] API Хрома: https://developer.chrome.com/extensions/api_index
[7] Cross-Origin Policy: https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image
[8] MHTML: http://en.wikipedia.org/wiki/MHTML
[9] API: https://developer.chrome.com/extensions/pageCapture
[10] вырезаю: https://github.com/sobnik/sobnik.chrome/blob/master/sobnik.js#L27
[11] хостинг: https://www.reg.ru/?rlink=reflink-717
[12] раздел: http://www.avito.ru/moskva/kvartiry/sdam/na_dlitelnyy_srok?p=4&user=1&view=list
[13] Источник: http://habrahabr.ru/post/237869/
Нажмите здесь для печати.