Привет всякому входящему! Сегодня хочу рассказать о том, как сложно спрогнозировать вроде бы простые задачи, на которые по словам «экспертов с интернета» уходит пару дней. Я поделюсь примерами из жизни, когда клиент просит сделать быстренько на коленке, а ты погрязаешь в рутине переделок.
У нас с командой есть такой проект, как homecrm.ru Мы долгое время работаем над автоматизацией бизнеса и уже получили много опыта, на основе которого можно проводить хоть какую-то экспертизу и прогнозирование плюс минус паровоз. За 7 лет разработки можем поделиться накопившемся багажом знаний, кучей получившихся проблем и путями их решений на основе этого стартапа.
С чего начинается идея
5 лет назад к нам приходит клиент и говорит: "Парни, я хочу собирать объявления с сайтов в один клик. Вот у меня список сайтов, на которые рекламируются все, кому не лень. Соберите мне всю информацию в реальном времени. Я готов заплатить за это 30 тысяч рублей."
Ну мы люди не гордые, провинциальные, можем и посмотреть. Заходим в интернет, видим статьи про парсинг на php, радуемся как ужаленные. ТЗ никакого нет, заказчик не составит его, так как сам ничего в этом не понимает. Для него есть конечная цель и ему совершенно фиолетово, какие мы технологии используем, и как оно будет работать. Лишь бы был достигнут результат. В принципе, это типичный клиент, ему и не нужно ни в чём разбираться. Это сейчас я понимаю, что надо было писать тех задание, а тогда был зеленый, неопытный.
Так вот. Мы, одурманенные чувством простой прибыли, на коленке за 5 дней сделали парсер. Простой скрипт, который проходит и собирает список объявлений с сайта (с ави*о. ру, никому не скажем об этом). Ставим на сервер, по крону запускаем раз в час — всё работает. Получаем деньги и идем пить пиво.
Проходит 3 дня. Клиент позвонил и говорит: "Парни, а там больше не работает ничего. Я же деньги дал, а вы чего пытаетесь кинуть меня чтоли." Лезем в код — поменялась вёрстка на сайте. Следовательно и скрипт перестал работать. Мы переделали и запустили заново. Ну вот сейчас то точно ничего не произойдёт (-нет).
Прошла еще неделя. Снова звонок и снова доработки. И так по кругу в течение полугода. Нам повезло, что клиент разорился и уехал жить в Краснодар. Иначе бы мы никогда с ним не закончили.
Вообще, мы читали в интернете и на всяких интернет-курсах, что парсинг — это просто. Там вообще не надо ни с чём долбаться. Просто собирай огромный объем данных и продавай их. Нюансов то вообще нет, а клиентов просто тьма тьмущая. Сейчас точно могу сказать — ЭТО НЕ ТАК.
Мы решили, что в нашу crm’ку тоже нужно добавить парсер недвижимости, а то 2 из 3 людей просят парсер. Вроде бы и опыт есть уже, и скрипт писали. Провели опрос среди наших клиентов, собрали список самых приоритетных задач (это же бизнес нам сказал, что важно и полезно, как можно бизнесу то не верить), погнали разрабатывать. По срокам реализации посчитали около 1 месяца кропотливой работы.
Далее я постараюсь описать таймлапс, по которому можно будет понять этапы разработки. Сразу говорю — точного ТЗ у нас нет, мы сами придумываем процесс и пытаемся его автоматизировать. Ни один клиент не смог нам рассказать все нюансы своей работы, т. к описать процесс в хоть сколь-нибудь адекватном виде является невозможной мукой.
1-я стадия MVP
Мы спарсили 3 сайта. На крон навесили задание, которое каждый день собирает инфу в одну большую базу для нашего города. Проработало 3 дня.
Список полученных проблем:
Забанили IP, по которому мы парсили. Пришлось купить прокси. Добавили просто массив в код с логинами паролями. (Да да, мы как неумелые люди взялись парсить напрямую с сервера, не плюйте только)
Скрипт может оборваться и перестать работать. Нужно понимать что мы спарсили, а что нет для его возобновления. Стали складывать в базу по урлам со статусами Успех, Не успех, Успех с ошибками.
Надо распарсить строку с адресом и положить к нам в систему. У нас под капотом кладр, который четко вписан в общую концепцию. А на сайтах просто строка. Долго искали адекватное решение, решили использовать сторонний сервис для распознавания строк.
Параметры не бьются на сайтах с нашими. У нас в системе определенные списки с параметрами, например с ремонтами. А тут с какого-то сайта вылазит ремонт с типом Хороший, Красивый, Нежный, Мягкий. Куда его присоединять? Пришлось извращаться и писать алгоритм соединения для каждой площадки отдельно.
2-я стадия полной переработки
Вроде бы работает MVP. Но тут видим, что 80% запросов отдаёт ошибку. Оказывается, что все сайты внедрили систему для распознавания ботов и парсинга. Полезли в интернет и на то время нашли Selenium. Пришла пора полного переписывания проекта.
Мы ставим 3 месяца проект на новые лыжи, с php на python. Прошли десятки бессонных ночей, но мы не могли добиться адекватного сбора данных. Все сайты постоянно банили запросы, а сам селениум из себя представлял один огромный костыль, который переписывается всеми, кому не лень. На гите можно найти тысячи форков, которые сверху реализации набрасывают свои костыли. На этой стадии мы хотели бросить проект т. к отказоустойчивости не было никакой. и мы не могли обещать качественный сервис своим клиентам.
Через 2 месяца всевозможных тестов у нас получился вроде бы рабочий парсер. Но снова возникли проблемы.
Список новых проблем:
Кривая архитектура синхронных запросов. Никогда не делайте синхронные запросы для таких больших проектов! Нам пришлось поднять RabbitMQ для разграничения по очередям запросов. Отдельно для каждой площадки, для каждой категории недвижимости. Это было очень сложная задача, за 2 месяца плюс минус управились. Но теперь у нас много воркеров, которые могут параллельно смотреть новые объекты по каждой категории.
Нам нужно обновлять старые объекты. Несколько клиентов одновременно начали просить архив за прошлые месяцы. Они хотели видеть все изменения по цене и параметрам. Объявление удалилось с сайта — должно пропасть и у нас. Решили отдельно создать очередь для таких объектов. Даже выставили приоритетность обновления. Пример: скачали объект, после через час проверили его на актуальность, далее через день, далее через 3 дня и там уже раз в неделю.
Из 2 проблемы пришла другая — постоянное накопление архива и увеличение количества объектов для парсинга. Архив копится, лавэха не мутится, ресурсы утилизируются, терпение кончается. Это самое узкое место на сегодняшний день, т. к мы не смогли найти решения, кроме как увеличить количество серверов, проксей и т. д
3-я стадия разработки
Один за одним сайты начали банить прокси. Мы начали анализировать и пришли к следующему списку проблем и решений.
Новые проблемы:
Бан одновременных прокси. Нельзя было обращаться в одно и то же время с одной прокси разными воркерами. Т. е мы не можем загружать 5 страниц с разных браузеров с одного ip одновременно, это распознается как парсер страницы сторонними средствами. Пришлось внедрять ротацию проксей, чтобы она занималась и отдавалась по времени.
Воркеры могли зависнуть. Можно было попасть в тот в момент недоступности прокси, либо браузер просто зависал и т. д Проблем с этим куча и они решились только перезапуском воркеров по таймауту. Грязное, но рабочее решение.
Прокси стали банить на долгое время. У нас кончилось 150 проксей. Просто все было заблочено на некоторых сайтах на неделю. Решение было найдено благодаря Максиму Кульгину, за что ему огромное спасибо. Мы стали использовать мобильные прокси. Да, это дорого. Но это того стоит. Получилось побороть полный бан по ip.
С увеличением количества площадок и сайтов стали кончаться ресурсы. Представьте запускать 30 гугл хромов одновременно. Процессоры не вывезут, память кончится и всё станет колом. Решение простое — увеличение серверов. На данный момент мы тратим около 50 тысяч на сервера в месяц. Но это мы только в начале этого сложного пути.
На данный момент мы решаем такие нюансы, как:
Парсер сайтов Казахстана. Нашли там коллег и выходим на их рынок. Там просто огромная проблема с адресами и отсутствием стандартизации всего и вся.
Увеличение доступных площадок и городов. Все упирается в серверные ресурсы и деньги.
Несколько месяцев назад к нам пришёл клиент, который попросил дать ему парсер, который будет в режиме реального времени собирать объявления с 20 сайтов и выводить в онлайн-форму. Он подключит колл-центр и будет обзванивать продавцов. Главное правило — объявление должно появиться в системе не более, чем через 5 секунд после публикации на сайте. Вы вообще представляете объёмы работы? На опыте я могу сказать, что это либо невозможно, либо очень дорого. Ну и заплатить он был готов не более 50 тысяч рублей т.к "на том же кворке такое же делают за 5к парочка студентов". До сих пор видимо никого не нашёл.
Технические дополнения
Отвечаю на комментарий по технической реализации.
Что делали после Selenium? - Selenium мы убрали из своей разработки полностью. Перешли на Playwright из-за его скорости и хорошей доки. Есть хороший сайт https://bot.sannysoft.com/ - можно проанализировать, как распознается ваш браузер. Если что-то горит красным - значит это автоматический браузер, который будет забанен после нескольких запросов к сайту. На Selenium мы не смогли добиться всех успешных тестов, а Playwright с некоторой долей магии смог успешно справиться с этим (на него надо ставить патчи, на гите лежат в отрытом доступе).
Как боролись с Cloudflare? - Ответ всё тот же - использовали браузер. Если правильно написать логику переходов, то система будет ждать полной загрузки страницы и после попытается собрать инфу.
Сталкивались ли с банами по подсетям? - По подсетям не сталкивались, т.к пытаемся не дудосить сайты огромным количеством запросов с одного ip. Для этого и придумали ротацию проксей + большое количество покупных проксей. Очень выручают мобильные прокси, для этого мы даже собрали свою мобильную ферму. Постараюсь техническую реализацию написать позже в отдельную статью.
А бан по геолокации? - После начала СВО очень много российских сайтов не открываются из под зарубежных проксей. Аналогично сайты в Казахстане часто банят прокси из России. Здесь помогает только покупка проксей с нужной гео. Мы берем пачками с разных сервисов со всех уголков страны.
Что делали с телефонами под авторизацией? - В начале пытались регистрировать десятки аккаунтов, запоминать куки и т.д. Но сейчас все сайты ввели IP-Телефонию и мы отказались от парсинга номеров в принципе. Временный номер постоянно меняется и смысла собирать архив с номерами нет. Запоминаем ссылку на страницу - пользователь сам перейдёт и позвонит куда надо. Вообще хороший вариант, чтобы клиенты сами обзванивали и писали в базу настоящие номера. Но мы таким не занимаемся.
Как парсим? - BeautifulSoup на Python. Каждый сайт является своей небольшой загадкой. Где-то приходится лезть в нутро библиотек и заниматься реверс-инжинирингом, а где-то всё лежит на поверхности. Так что нельзя сказать про один конкретный подход, всё полностью индивидуально. Но весь парсинг мы стараемся делать на Playwright. Зато мы столько кеков и мемов увидели в коде, что можно поэму написать. Очень понравились ребята с Домклика, они отдают данные в методах очень классно, аля 'Упс, а как ты сюда попал? Приходи к нам на работу, писать вот на эту почту'.
Заключение
Вроде бы есть понятная задача бизнеса, которая по статьям из интернета решается за пару дней. Но она имеет такой огромный айсберг проблем, о котором без опыта ты даже не сможешь догадаться.
Проблемы не кончаются никогда. Это закон бизнеса. Мы стараемся сделать продукт таким, чтобы он был удобным, быстрым и безотказным. У меня просто совести не хватит продавать то, от чего ты не получишь душевного экстаза.
Буду рад любой обратной связи. Мы умеем парсить всё, до чего дойдут руки. Пишите , поболтаем :-)
P.S. Никакого парсинга персоналки, данных под авторизацией и незаконной инфы. Я ещё молод, чтобы сидеть.
Пока писал текст - нашёл багу.
https://t.me/itpriton — я тут пишу периодически о бизнесе и всяком интересном. Заходите, поболтаем.