- PVSM.RU - https://www.pvsm.ru -

Поиск жилья без посредников в 21-м веке

Полагаю, все мы однажды искали себе жилье. Кто-то — в собственность, большинство, вероятно, в аренду. Все, кто хоть раз пытался найти реальные предложения на досках объявлений, знают — это нереально. Такого количества спама нет, пожалуй, ни в одной другой сфере. После того, как окунешься в этот ад, обычно руки начинают чесаться применить свою 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.

Как выявить агентов?

На первый взгляд — довольно просто. Доступным и достоверным индикатором служит номер телефона, на который дано множество объявлений. Ведь не станет же агент покупать под каждое объявление новую сим-карту! Кроме того, некоторые объявления содержат прямые упоминания что автор риэлтор и хочет комиссию. В теории оно конечно просто, на практике пришлось решать множество мелких вопросов:

  1. Авито и многие другие доски публикуют номер телефона в виде изображения, соответственно — номер приходится распознавать.
  2. Агенты активно прячут свои реальные телефоны. Телефон указывают в тексте объявления, словами, буквами, спецсимволами. Всю эту маскировку приходится выявлять и вскрывать.
  3. Некоторые собственники дают много объявлений на одну и ту же квартиру. Чтобы не зачислить их в риэлторы, приходится выяснять, о разных объектах идет речь в разных объявлениях, или об одном и том же. Связываться с распознаванием адресов я не стал, использую готовые географические координаты, доступные на многих досках.
  4. Самые продвинутые посредники рисуют свои реальные номера телефонов на фотографиях квартир. Таких товарищей сложнее всего выявить. Я не нашел надежного и легкого в применении OCR [5] решения, способного распознавать номера на фотках. Пришлось покумекать и родить простой алгоритм, определяющий, есть ли на фото какой-либо текст, и такие объявления считать агентскими.
  5. В тексте объявления часто есть прямое упоминание о том, что автор — агент. Однако, поскольку компьютеры пока не научились понимать речь, надежного метода для полноценного использования этой информации я не придумал. Пока обошелся обнаружением некоторых наиболее распространенных и недвусмысленных фраз, благо этот критерий лишь дополняет основной детектор по номерам телефонов.

Использование этих приемов позволяет автоматически выявлять большую часть посредников. Вот так выглядит Авито во время активности спамеров (красные и зеленые кружочки — результат работы Sobnik-а):
image

Техническая сторона проекта

Плагин написан на JavaScript, поскольку функционала API Хрома [6] вполне достаточно для поставленных целей. Единственная сложность была с получением изображения номера телефона. Дело в том, что Avito отдает его только для запросов с правильным Referer-ом. В браузере подделать этот заголовок возможности нет, а получить данные изображения, загруженного страницей Avito, не дает Cross-Origin Policy [7]. Оказалось, что эту защиту легко обойти — я сохраняю страницу в формате MHTML [8] через соответствующий API [9], а затем из полученной строки вырезаю [10] нужный мне кусок, содержащий изображение в base64-кодировке. Таким же методом получаю доступ и к фотографиям квартир.

Далее, информация отправляется на сервер, где работает программа на Go. На самом деле две программы — все запросы выполняются асинхронно, одна программа пишет все запросы в очередь, вторая программа эти запросы обрабатывает. В клиентскую часть встроена логика по замедлению потока обращений к серверу в случае, если тот не успевает выполнять запросы вовремя. Такой подход позволит сгладить скачки нагрузки (очень надеюсь, что сегодня они возникнут). Данные хранятся в MongoDB.

Все это хозяйство я разместил на Amazon AWS (еще одна штука, которую хотел попробовать). Пока «Free Tier» вполне хватает, так что за хостинг [11] не плачу.

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

Исходный текст плагина открыт [4]. Во-первых, все равно его не скроешь. Во-вторых, сразу видно какую именно информацию собирает плагин, так что у понимающих людей не будет вопросов касаемо приватности. Ну и, наконец, вдруг однажды появятся энтузиасты, желающие поучаствовать в разработке.

Централизованного краулера для сбора данных нет. Во-первых, Авито отрубает IP-шники, которые открывают порядка пары сотен страниц в час. Во-вторых, я надеюсь, что когда пользователей станет много, получится распределенный краулер — каждый откроет по паре объявлений, вот и наполнилась база. Однако, пока активных пользователей нет — база пуста. Основная польза от плагина в том, что не надо открывать агентские объявления, а если в базе пусто — то открывать придется все подряд. В общем, чтобы придать системе хоть какое-то ускорение, я сделал еще один плагин для внутреннего использования, который тихонько, примерно по страничке в минуту, сканирует на Авито предложения о сдаче квартир в Москве. Успевать за спамерами в пиковые часы не получается, но все же у вас, уважаемый читатель, будет возможность оценить как работает Sobnik: установили, открывайте на Авито вышеуказанный раздел [12] и наслаждайтесь. Буду рад предложениям о том, как наладить сканирование Авито в более серьезных масштабах. Желающим могу выдать плагин для краулинга, если вдруг хотите помочь проекту или посканировать другой город или раздел.

Наблюдения за риэлторами

Запустив сканирование аренды в Москве, я сделал несколько полезных наблюдений. Все они довольно логичны и кажутся очевидными, однако Sobnik позволил их наглядно проверить и подтвердить:

  1. В рабочие дни порядка 80% объявлений принадлежат агентам. Авито, кстати, активно банит очень много объявлений, так что из 30 объявлений в минуту через час остается от силы 10. Однако, из этих десяти все равно подавляющее большинство — посредники.
  2. Поздно вечером (после 10-11 часов), и в выходные — агентов почти нет. Отдыхают видать от тяжелых спамерских будней.
  3. Платные объявления (на Авито они выделены желтоватым цветом) — почти всегда собственники. Пока я видел только одного агента, не пожалевшего сотню рублей на рекламу элитной квартиры. Есть вероятность, что это был собственник, решивший сделать вид что он агент с эксклюзивом и срубить лишних денег (бывают такие, судя по слухам).
  4. Если в объявлении всего одна или две фотографии, это почти наверняка агент. Три фотки — 50 на 50. Собственники либо пишут вообще без фото, либо уж если напряглись — делают хотя бы пяток.
  5. Если телефон указан на фотографии, либо «зашифрован» в тексте объявления — это почти наверняка агент. Шифроваться подобным образом их заставляет Авито, который требует денег за размещение большого количества объявлений на один и тот же номер телефона.

Этот список, в целом, позволяет глазами отфильтровать почти весь мусор, так что если вам лень ставить Sobnik — пользуйтесь.

Disclaimer: Я ни сколько не против риэлторов. Для них на Авито если специальная галочка, ставишь её — и всем сразу понятно что ты — агент. И конечно я в курсе, что во многих случаях агент просто необходим. Sobnik борется лишь с теми, кто спамит и пытается вас обмануть.

Перспективы

Развивать проект я планирую в двух направлениях:

  1. Добавлять новые доски (следующей, вероятно, будет «Из рук в руки»).
  2. Повышать точность и надежность детектора.

Теоретически, когда будет активно сканироваться много досок, 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/