Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

boards.by parser

Парсер рекламных поверхностей с boards.by с экспортом в JSON и XLSX.

Что делает

  • Забирает полный каталог конструкций через POST https://boards.by/local/ajax/map.php.
  • Разбивает PROPERTY_SIDE_VALUE на отдельные стороны.
  • Для выбранных конструкций догружает карточки вида https://boards.by/banner/{code}/?side={side}.
  • Нормализует поля под тестовый формат.
  • Выгружает результат в result.json и result.xlsx.

Запуск

python -m pip install -r requirements.txt
python main.py

По умолчанию парсер собирает:

  • минимум 100 уникальных конструкций (gid)
  • минимум 150 side-записей

и сохраняет результат в:

  • result.json
  • result.xlsx

Можно изменить лимит и пути:

python main.py --limit-gids 120 --limit-sides 220 --json-out custom.json --xlsx-out custom.xlsx --verbose

Структура проекта

  • main.py - CLI entrypoint.
  • boards_parser/client.py - HTTP-клиент и запросы к boards.by.
  • boards_parser/parser.py - отбор конструкций, парсинг карточек, сбор целевых записей.
  • boards_parser/normalize.py - нормализация сторон, размеров, типов и форматов.
  • boards_parser/exporters.py - экспорт в JSON и Excel.

Логика парсинга

1. Каталог

Основной источник списка конструкций - JSON из POST /local/ajax/map.php.

Из него берутся:

  • ID как реальный gid.
  • NAME как fallback для адреса.
  • CODE для перехода в карточку.
  • PROPERTY_SIDE_VALUE для разбиения на стороны.
  • PROPERTY_TYPE_VALUE как исходный тип конструкции.
  • PROPERTY_LONGITUDE_VALUE и PROPERTY_LATITUDE_VALUE для координат.

2. Стороны

Одна конструкция на сайте может содержать несколько сторон в одном поле, например:

  • А,В
  • А1,А2,А3
  • A,B,C,D

Парсер делит такое значение на отдельные записи. Новые gid не генерируются: если сайт показывает один ID на конструкцию, этот ID повторяется у всех ее сторон. Это сознательно сделано, потому что отдельные side-id источник не публикует.

3. Карточка конструкции

Из карточки добираются:

  • заголовок страницы для address;
  • блок dl_element для Формат, Тип, Сторона и других свойств;
  • описание конструкции для fallback-парсинга display_type и size.

Нормализация

Координаты

У источника поля координат названы наоборот:

  • PROPERTY_LONGITUDE_VALUE фактически содержит lat
  • PROPERTY_LATITUDE_VALUE фактически содержит lon

Парсер это явно исправляет в итоговой выгрузке.

display_type

Используется комбинация поля Тип и текста описания.

  • Призматрон, Призмавижн -> Призматрон
  • Скролл или явное упоминание скролл в описании -> Скроллер
  • LED - экран, Светодиодный экран, Экран -> Видеоэкран
  • если источник явно указывает на динамическую конструкцию, но не позволяет надежно отнести ее к одному из допустимых классов -> null
  • во всех остальных случаях -> Статика

construction_format

Используется поле Тип.

  • Билборд -> Билборды
  • Арка -> Арки
  • Путепровод -> Мосты
  • Брандмауэр -> Брандмауэры
  • Ситиборд -> Ситиборды
  • Световой короб, Юнипол, Мегаборд, а также типы, которые описывают только механику показа (Призматрон, Скролл, Экран) -> Нетиповые форматы

Почему Нетиповые форматы: сайт в поле Тип смешивает физический формат конструкции и технологию показа. Для части объектов надежно восстановить формат из справочника нельзя.

size

Нормализация размеров:

  • разделители х, ×, * приводятся к x
  • убираются пробелы и единицы измерения
  • запятая приводится к точке
  • если размер указан в миллиметрах или сантиметрах, он конвертируется в метры

Примеры:

  • 6*3м -> 6x3
  • 8 х 4 м. -> 8x4
  • 3,72х2,74 м -> 3.72x2.74
  • 6020*3080мм -> 6.02x3.08

Если в источнике нет пары размеров, поле остается null.

lighting

Заполняется только когда признак можно определить надежно:

  • true для явно светящихся носителей вроде LED - экран, Светодиодный экран, Экран, Световой короб
  • true или false, если в карточке когда-либо появится явное поле Подсветка/Освещение
  • иначе null

material

Заполняется только из явного поля карточки. Если сайт не отдает материал, в выгрузку идет null.

Отбор записей

Чтобы в тестовой выгрузке были представлены разные типы конструкций, конструкции отбираются не просто по первым ID, а раундами по Типу. Это дает более показательный набор объектов для проверки маппинга.

--limit-gids задает минимальное число уникальных конструкций.

--limit-sides задает минимальное число side-записей.

Обе границы применяются одновременно: парсер останавливается только когда выполнены оба условия. Последняя конструкция не режется по сторонам, поэтому итоговое количество строк может быть чуть больше запрошенного.

Ограничения источника

  • Сайт не публикует отдельные идентификаторы сторон, только идентификатор конструкции.
  • Поле Тип неоднородное: часть значений описывает формат носителя, часть - способ смены изображения.
  • material почти нигде не указан явно.
  • lighting для статических конструкций чаще всего не указан явно, поэтому массово выставляется null, а не предположение.
  • В постановке есть расхождение: в примере JSON поле называется Material, а в таблице правил - material. В реализации используется material, потому что это соответствует общему стилю остальных ключей и разделу с правилами заполнения полей.

Формат результата

JSON:

{
  "construction_sides": [
    {
      "gid": "10118",
      "address": "№ 1 г.Молодечно, угол ул.Виленская - ул.Толстого (Центральная площадь)",
      "name": "В",
      "lon": 26.839621,
      "lat": 54.307023,
      "construction_format": "Билборды",
      "display_type": "Статика",
      "lighting": null,
      "size": "6x3",
      "material": null
    }
  ]
}

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages