Цены в долларах на Kufar.by

Страницы:  1

Ответить
 

Professor Seleznov


Kufar.by - это примерно как avito.ru, только в Беларуси. После очередного “улучшения” там стало невозможно выбирать авто и недвижимость: цены показываются только в белорусских рублях, хотя рынок всегда будет в долларах (боже, храни Америку). Поэтому я сделал небольшой Chrome Extension, который добавляет рядом ориентировочную цену в долларах. Пока только для авто и недвиги. И да, по ощущениям, ЛПРы, которые это выкатывали, никогда не покупали ни то ни другое на своём сайте.
Пролог
Попытка #1
Цена в долларах. Верните обратно! Невозможно ориентироваться.
Первоначальное сообщение с претензией (которое отправлял в форме на сайте) не цитируется в почте, только ответ. Что уже странно, но “это база”. Получил вот такие волшебные ответы:
Ответ #1
По белорусскому законодательству расчёты и ценообразование внутри страны должны производиться в национальной валюте, то есть в белорусских рублях.
Раньше продавцы часто указывали цены в долларах, так как рынок недвижимости исторически был привязан к иностранной валюте. Чтобы не вводить покупателей в заблуждение и избежать путаницы (например, когда цена написана в долларах, а подразумевается в белорусских рублях), мы приняли решение изменить отображение цен на объекты недвижимости, приведя все объявления к единому стандарту.
Данное решение также основано на новых требованиях законодательства, касающихся оформления договоров с агентствами недвижимости, где цены фиксируются исключительно в белорусских рублях.
При этом мы стремимся максимально сохранить удобство для наших пользователей: возможность подачи объявления и фильтрацию предложений по валюте мы оставляем. Это позволяет вам по-прежнему работать с привычными ориентирами и находить наиболее подходящие варианты.
Если остались вопросы, то, пожалуйста, спрашивайте. Буду рада помочь.
Попытка #2
Вы не думаете о своих пользователях. Сижу с калькулятором и пересчитываю цену каждого объявления. Кто это придумал… С другой стороны, у конкурентов есть возможность извлечь свою пользу. Может это и к лучшему.
Ответ #2
Андрей, мы понимаем, что эти нововведения могли доставить неудобства, при этом следует учитывать, что данное решение также основано на требованиях законодательства.
Мы стремимся максимально сохранить удобство для наших пользователей: возможность подачи объявления и фильтрацию предложений по валюте мы оставляем. Также технические специалисты занимаются вопросом добавления валютного калькулятора.
Благодарим вас за обратную связь и что решили с нами поделиться мнением ☺️
Попытка #3
realt.by & onliner.by указывают “ориентировочную цену” в долларах, а вам можно пожелать удачи.
Ответ #3
А нет ответа.
Хватит это терпеть
Но зачем спорить, когда можно сделать себе требуемый интерфейс поверх текущего - #тыжеинженер. Нужен небольшой Chrome Extension, который открывает страницы Куфара, находит цены в белорусских рублях и рядом показывает приблизительную цену в долларах.
Без аккаунтов, без серверной части, без прокси. Просто контент-скрипт и курс НБРБ.
Исходники лежат тут: comerc/try-kufar.
Что получилось
Расширение работает на двух доменах (авто и недвига):
{
"content_scripts": [
{
"matches": [
"https://auto.kufar.by/*",
"https://re.kufar.by/*"
],
"js": ["src/content.js"],
"css": ["src/content.css"],
"run_at": "document_idle"
}
]
}
Идея простая: на странице есть цены вида 68 683 р. или 256 873 р.. Скрипт превращает их в:
68 683 р. <span class="kufar-usd-price">≈ 25 165 $</span>
Выглядит как маленький зелёный бейдж. Не замена цены, а подсказка рядом.
Курс доллара
Курс берётся из официального API Нацбанка:
const RATE_URL = "https://api.nbrb.by/exrates/rates/USD?parammode=2";
Запрос делает не content script, а background service worker. Так меньше сюрпризов с CORS и проще хранить кеш.
chrome.runtime.onMessage.addListener((message, _sender, sendResponse) => {
if (!message || message.type !== "kufar:getUsdRate") {
return false;
}
getUsdRate()
.then((rateInfo) => sendResponse({ ok: true, rateInfo }))
.catch((error) => sendResponse({ ok: false, error: error.message }));
return true;
});
Кеш на 6 часов:
const CACHE_TTL_MS = 6 * 60 * 60 * 1000;
Если API временно не отвечает, берётся последнее сохранённое значение. Для такой задачи этого более чем достаточно: это не трейдинг, это “понять порядок цены”.
Как ищем цены на странице
У Куфара много разных блоков. Листинг, страница объявления, попап на карте, “Похожие объявления”, “Ранее вы смотрели”, автостраницы. Классы тоже не подарок: CSS modules, хеши, разные компоненты. (Бардак в танковых войсках).
Поэтому привязываться к одному классу нельзя. Основной поиск идёт по текстовым узлам:
const PRICE_RE = /(^|[^\d])(\d[\d\s\u00a0.,]*?)\s*(р\.|руб\.?|BYN)(?=$|[^\wа-яё])/i;
Дальше TreeWalker проходит по тексту страницы:
const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
acceptNode(node) {
return isPriceTextNode(node)
? NodeFilter.FILTER_ACCEPT
: NodeFilter.FILTER_REJECT;
}
});
Но этого мало. Иногда цена разбита по вложенным span, иногда лежит в блоке с class*="price". Поэтому есть второй проход:
const candidates = root.querySelectorAll([
"[class*='price' i]",
"[data-testid*='price' i]",
"[aria-label*='цен' i]",
"[aria-label*='price' i]"
].join(","));
Это не идеально академически, зато устойчиво к реальной вёрстке.
Динамический DOM
Куфар дорисовывает части страницы после загрузки. Например, попап на карте появляется не сразу. Поэтому обычного запуска один раз недостаточно.
Решение стандартное:
const observer = new MutationObserver(() => {
clearTimeout(scanTimer);
scanTimer = window.setTimeout(() => scanPrices(), 250);
});
observer.observe(document.body, {
childList: true,
subtree: true,
characterData: true
});
Каждое изменение DOM не сканируется мгновенно. Есть debounce на 250 мс, чтобы не устроить странице маленький стресс-тест.
Конвертация
Сама математика смешная:
badge.textContent = `≈ ${formatUsd.format(byn / rateInfo.rate)}`;
Форматирование через Intl.NumberFormat:
const formatUsd = new Intl.NumberFormat("ru-RU", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0
});
То есть 87 914 р. превращается примерно в ≈ 32 212 $.
Несколько неприятных мелочей
Самое интересное было не в курсе и не в регулярке. Самое интересное было в вёрстке.
Например, похожие объявления внизу страницы имеют overflow: hidden и text-overflow: ellipsis. Бейдж добавлялся, но для длинных цен просто обрезался. Пришлось помечать строку цены своим классом и разрешать перенос:
p.kufar-usd-price-row {
display: flex !important;
flex-wrap: wrap;
gap: 2px 0 !important;
overflow: visible !important;
text-overflow: clip !important;
white-space: normal !important;
}
Для аренды есть отдельная история: 604.41 р. / мес.. После добавления доллара суффикс / мес. переставал влезать. Его пришлось вынести в отдельный span и принудительно отправить на новую строку:
.kufar-usd-rent-suffix {
display: inline-flex;
flex-basis: 100% !important;
}
А ещё на автостранице есть кнопка “Оформить в лизинг от … р. /м.”. Это не цена объявления, поэтому такие блоки пропускаются:
const SKIP_CONTEXT_RE = /лизинг|\/\s*м\./i;
В итоге расширение конвертирует основную цену авто, но не лезет в платежи по лизингу.
Установка из исходников
Пока расширение не в Chrome Web Store, ставится как unpacked extension.
git clone https://github.com/comerc/try-kufar.git
cd try-kufar
Дальше в Chrome:
  • открыть chrome://extensions;
  • включить Developer mode;
  • нажать Load unpacked;
  • выбрать папку try-kufar;
  • открыть страницу Куфара.
Если меняли код локально, надо нажать reload у расширения на странице chrome://extensions, а потом перезагрузить вкладку с Куфаром. Это важно: content scripts и CSS не всегда обновляются просто по F5.
Итог
Получился маленький пользовательский слой поверх сайта. Куфар показывает цены в белорусских рублях, как ему хочется или как ему надо. Расширение рядом показывает привычный ориентир в долларах.
Никакой магии. Просто немного DOM, MutationObserver, API Нацбанка и терпение к чужой вёрстке. Codex решил проблему за пару часов!-Источник
 
Loading...
Error