Device Detector

May 18, 2026 · View on GitHub

English version

Device Detector - Crystal shard для разбора строк User-Agent. Он определяет ботов, браузеры, движки браузеров, операционные системы, клиентские приложения, устройства, производителей, модели и несколько специализированных классов устройств: телевизоры, камеры, консоли, автомобильные браузеры и портативные медиаплееры.

Парсер использует regex-данные из matomo-org/device-detector, генерирует token indexes для самых крупных наборов правил и встраивает regexes и indexes в shard на этапе компиляции.

Установка

Добавьте shard в shard.yml приложения:

dependencies:
  device_detector:
    github: creadone/device_detector

Затем установите зависимости:

shards install

Использование

require "device_detector"

user_agent = "Mozilla/5.0 (Windows NT 6.4; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.143 Safari/537.36 Edge/12.0"

response = DeviceDetector::Detector.new(user_agent).call

response.browser?             # => true
response.browser.name         # => "Microsoft Edge"
response.browser.version      # => "12.0"
response.os.name              # => "Windows"
response.os.version           # => "10"
response.traffic_type         # => "human"

Используйте #call, чтобы запустить полный стек парсеров. Используйте #lite, если нужны только определение бота и мобильного устройства:

full_response = DeviceDetector::Detector.new(user_agent).call
lite_response = DeviceDetector::Detector.new(user_agent).lite

Response#raw возвращает сырой результат парсеров:

pp response.raw

Сырое значение имеет тип Array(Hash(String, Hash(String, String))). Отсутствующие значения представлены пустыми строками в raw-данных; типизированные accessors возвращают String?.

Response API

У каждой обнаруживаемой секции есть predicate и object-style accessor:

response.browser?        # => Bool
response.browser.name    # => String?
response.browser.version # => String?

Доступные секции и поля:

SectionPredicateFields
Botbot?bot.name
Browserbrowser?browser.name, browser.version
Browser enginebrowser_engine?browser_engine.name
Cameracamera?camera.device, camera.vendor
Car browsercar_browser?car_browser.model, car_browser.vendor
Consoleconsole?console.model, console.vendor
Feed readerfeed_reader?feed_reader.name, feed_reader.version
Librarylibrary?library.name, library.version
Mediaplayermediaplayer?mediaplayer.name, mediaplayer.version
Mobile appmobile_app?mobile_app.name, mobile_app.version
Mobile devicemobile?mobile.vendor, mobile.type, mobile.model
OSos?os.name, os.version
PIMpim?pim.name, pim.version
Portable media playerportable_media_player?portable_media_player.model, portable_media_player.vendor
TVtv?tv.model, tv.vendor
Vendor fragmentvendorfragment?vendorfragment.vendor

Legacy flat accessors остаются доступными для совместимости:

response.browser_name
response.browser_version
response.mobile_device?
response.mobile_device_vendor
response.mobile_device_type
response.mobile_device_model
response.camera_model

Traffic Type

Response#traffic_type возвращает "bot", если обнаружен бот или клиентская библиотека. В остальных случаях возвращается "human".

response.traffic_type # => "bot" | "human"

Benchmarks

Запуск benchmark в release mode:

crystal run --release bench/raw_response.cr

Пример результата для разбора 10 000 уникальных user-agent строк:

Crystal 1.17.1 (2025-07-22)
LLVM: 21.1.0
Default target: aarch64-apple-darwin23.1.0

workload: 10000 unique user-agents
full:  7807.40 user-agent/sec (1.280836s)
lite: 28040.29 user-agent/sec (0.356630s)

Benchmark требует минимальную скорость full parser в 150 user-agent/sec.

Парсер хранит generated token indexes для самых больших и быстрорастущих наборов правил: bots, browsers, operating systems и mobile devices. Индексы сужают список regex-кандидатов перед fallback на полный scan правил и при этом сохраняют исходный приоритет YAML-правил.

Разработка

Установите зависимости:

shards install

Запустите тесты:

crystal spec

Запустите linter:

bin/ameba

Проверьте форматирование:

crystal tool format --check src spec script bench

Обновление Regexes

Regex-файлы лежат в src/device_detector/regexes и основаны на matomo-org/device-detector.

Чтобы обновить их:

crystal run script/update_regexes.cr
crystal spec
bin/ameba

Скрипт обновления скачивает upstream regexes, зеркалит только regexes/**/*.yml и пересоздает token indexes в src/device_detector/regexes/index. Перед коммитом нужно проверить и закоммитить diff regexes вместе с diff generated indexes.

Contributing

  1. Сделайте fork репозитория.
  2. Создайте feature branch.
  3. Внесите изменение и добавьте тесты, если меняется поведение.
  4. Запустите crystal spec, bin/ameba и проверку форматирования.
  5. Откройте pull request.

Contributors

  • @creadone Sergey Fedorov - creator, maintainer
  • @delef Ivan Palamarchuk - new API, code optimization
  • @zaycker Yuriy Zaitsev - parser order fix