# ПлюсАгент. ТЗ на импорт объявлений со сторонних площадок Данное ТЗ описывает процесс загрузки объявлений с классифайдов "Авито" и "Циан" для платформы ПлюсАгент. ## Прототип Прототип доступен по [ссылке](https://www.figma.com/proto/Gs4n0ZHP3m9mdUcwDAqXpf/PlusAgentNew-%D0%98%D0%BC%D0%BF%D0%BE%D1%80%D1%82-%D0%BE%D0%B1%D1%8A%D1%8F%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F?node-id=1%3A2&scaling=min-zoom). На первом экране необходимо нажать на ссылку "загрузить из площадки объявлений". Далее приведён перечень возможных вопросов и ответов по данному прототипу. #### На втором экране прототипа пользователю предлагается ввести ссылку. Какие правила валидации этого поля? Поле не должно быть пустым. Поле должно содержать ссылку; если опущен протокол (`https://` или `http://`), подставлять `https://`. Если вставлена некорректная ссылка, вывести ошибку валидации *"Указана неправильная ссылка"*. Возможные домены: `avito.ru` и `cian.ru` (а также `www.avito.ru`, `www.cian.ru`). Если указан некорректный домен, вывести ошибку валидации *"Укана ссылка на неподдерживаемую площадку объявлений. К сожалению, на данный момент невозможно загрузить это объявление."*. #### Что делать, если ссылка содержит некорректное объявление? Действительно, система на данный момент поддерживает не все типы (и категории) объявлений. Кроме того, на сайтах Циан, и тем более Авито большое количество "неподходящих страниц". Поэтому процесс парсинга необходимо разделить на две стадии - проверка страницы и загрузка данных. Проверка страницы приблизительно сводится к двум шагам: 1. Определить, является ли данная страница объявлением по недвижимости. В случае, если нет, вывести ошибку валидации *"Указаная ссылка не содержит объявление по недвижимости"*. Это можно сделать, например, по URL-адресу. 2. Определить, имеет ли объявление нужный тип (и категорию) объявления. При проверки типа иметь ввиду, что список поддерживаемых типов будет расширяться (см. раздел ["Нефункциональные требования"](#Нефункциональные-требования), пункт 1) #### На третьем экране поля формы (Категория, Тип, Адрес) уже заполнены. Подразумевается, что это сделал пользователь, или система сама заполнила поля? Подразумевается, что система заполнила поля сама. Поля "Категория" и "Тип" система уже определила, так как объявление должно было пройти проверку (см. предущий вопрос). Поле "Адрес" можно заполнить следующим образом: 1. Получить координаты объекта из объявления (для этого нужно будет понять, как получить их из карты) 2. Отправить координаты в геокодер (сервис реализован в классе `HereMapsGeocodeService`) и подставить полученный адрес Если получить координаты из карты не получится, можно отправлять в геокодер строковое представление адреса. #### На третьем экране формы содержится название объявления. Как его получить? Необходимо спарсить тег `<title>` и убрать оттуда упоминание площадки. Примеры: - Заголовок `Продаю многокомнатную квартиру 259м² Университетская ул., 9, Сургут, Ханты-Мансийский АО, мкр. 19-й - база ЦИАН, объявление 205254965` нужно привести к `Продаю многокомнатную квартиру 259м² Университетская ул., 9, Сургут, Ханты-Мансийский АО, мкр. 19-й`, - Заголовок `Коттедж 385.9 м² на участке 3 сот. в Сургуте | Недвижимость | Авито` привести к `Коттедж 385.9 м² на участке 3 сот. в Сургуте` ## Дополнительные сведения ### Поля для объявлений на площадках Список полей можно определить по формату XML-импорта площадок: - [Формат XML Циан](https://www.cian.ru/xml_import/doc/#common_cat) - [Формат XML Авито](https://autoload.avito.ru/format/realty/) ### Примеры объявлений для парсинга Ниже перечислены наиболее заполненные объявления типов "Квартира" и "Дом" на площадках. - [Циан, квартира](https://surgut.cian.ru/sale/flat/205254965/). Обратить внимание на раздел "Общая информация" и "О доме" - [Циан, дом](https://surgut.cian.ru/sale/suburban/233379163/). Обратить внимание на раздел "Общая информация" - [Авито, квартира](https://www.avito.ru/surgut/kvartiry/6-k_kvartira_210_m_55_et._1264724113) - [Авито, дом](https://www.avito.ru/surgut/doma_dachi_kottedzhi/kottedzh_385.9_m_na_uchastke_3_sot._1932985260) В случае удаления перечисленных объявлений можно [скачать сохраненные версии страниц](https://gofile.io/d/J3cZzJ). ## Нефункциональные требования #### 1. Архитектура парсинга должна быть расширяемой Решение должно быть спроектировано таким образом, чтобы в дальнейшем можно было быстро добавить: - парсинг других типов объявлений, в частности "Гаражи" и "Коммерческая недвижимость" - другие площадки объявлений #### 2. Логика загрузки страниц должен быть выделена в отдельный сервис В дальнейшем, возможно, придётся усложнять логику загрузки (т. е. код, получающий html-код страницы объявления). Например, Циан периодически показывает капчу вместо страницы, и необходимо будет закупить пул прокси-адресов и делать запросы через них. Эта логика не связана с предметной областью и должна быть выделена в отдельный сервис снаружи `domain`-слоя. ## Рекоммендации по выполнению #### Библиотека cheerio Для непосредственно извлечения данных из html-страницы можно использовать библиотеку [cheerio](https://github.com/cheeriojs/cheerio). Она предоставляет знакомый jQuery-синтаксис, который позволяет с помощью css-селекторов быстро извлечь нужные данные из DOM-дерева.