Описание проблемы
Понадобилось тут как-то отслеживать появление некоторых позиций на Digikey (в эту же группу входят всякие кастомные разъёмчики от SAMTEC, например, под мезонин FMC) и в какой-то момент это надоело делать, открывая периодически сохраненную ссылку, а уж коль скоро не пристало последние годы заниматься Design Automation, то и тут пришлось в очередной раз сесть за «клавикорд».
ТЗ на проблему и черновик решения
NB! Несмотря на богатый API Digikey [https://api-portal.digikey.com/] с удобным интерфейсом и кучей примеров начиная с bash & php и заканчивая Go & Swift [https://api-portal.digikey.com/node/3287], в первую очередь задал себе цель показать мощь и изящество инструментов для DOM-парсинга страниц и принципа «каждой задаче — свой инструмент».
Для решения поставленной задачи используем так ненавистный ЕЕ-сообществом и так любимый мной за быстрый старт (минимум кодинга) и множество примеров интерпретируемый язык PHP. Помимо самого интерпретатора нам понадобится библиотека PHP Simple HTML DOM Parser[http://simplehtmldom.sourceforge.net/], которая распарсит любой HTML с фиксированной структурой легко и непринуждённо, впрочем понадобится она номинально, поскольку устанавливать самому ничего не надо — она скачивается автоматически из мейкфайла, если отсутствует в директории запуска скрипта.
На входе скрипта должны быть партнамберы электронных компонентов, которые нам надо периодически пробивать на наличие у поставщика, но мне удобнее давать конкретную ссылку, поэтому в файле partnumber.list будет просто список URL-адресов наблюдаемых компонентов в формате: каждый URL с новой строки (лишние пробелы в начале и в конце строк удаляются внутри скрипта).
На выходе скрипта желаем получить уведомление о появлении у поставщика компонентов из списка в partnumber.list в удобном для нас формате:
- в виде письма на email
- в виде сообщения в телеграм-клиенте
- в виде push-уведомления на смартфоне, например через ранее обозреваемое приложение PushOver: http://idoka.ru/pushover-notifications-on-gadgets/
В самом теле сообщения хотим видеть что за компонент (партнамбер) появился, его количество в наличии и стоимость (в US$, для кого интересно в рублях — можно запрашивать через API текущий курс и пересчитывать налету).
Сам скрипт будем пускать по cron с подходящим нам периодом.
Подробности решения
Тут всё достаточно просто и лаконично: парсим файл со ссылками и запускаем цикл foreach. Далее, получив страницу через curl, используем всю мощь Simple HTML DOM Parser, а именно, нам надо найти в исходнике страницы якоря следующих элементов: партнамбер, количество в стоке и цена за 1 шт.
Партнамбер
Партнамбер можно вытянуть из нескольких мест файла, остановимся на одном, а именно:
1 2 3 4 5 6 7 | <tr> <th>Manufacturer Part Number</th> <td> <meta itemprop="name" content="0459704305" /> <h1 itemprop="model">0459704305</h1> </td> </tr> |
Из этого кода следует, что нам надо сообщить simplehtmldom, что надо извлечь партнамбер из уникального для текущей страницы сочетания: содержимое тега h1, у которого атрибут itemprop установлен в значении «model»:
1 | $html->find('h1[itemprop=model]') |
Количество
1 2 3 | <th>Quantity Available</th> <td id="quantityAvailable"> <span id="dkQty">0</span> |
В нотации simplehtmldom запишем действие «найти содержимое тега span с id=dkQty»:
1 | $html->find('span#dkQty') |
Цена
1 2 3 4 5 6 7 | <td >1</td> <span itemscope itemtype="http://schema.org/PriceSpecification"> <td itemscope itemtype="http://schema.org/UnitPriceSpecification"> <span itemprop="price" id="schema-offer" >32.4000</span> </td> </span> <td >32.4</td> |
На языке simplehtmldom это означает найти содержимое тега span с якорем itemprop в значении price:
1 | $html->find('span[itemprop=price]') |
Также перед этим не лишним было убедиться что это единственный элемент на странице (обычно присутствуют оптовые цены за 10, 25, 50, 250шт, но у них другие якоря).
Итог работы скрипта
Возможные альтернативные применения
Модифицировав, скрипт можно использовать не только для начальной задачи, но и для множества иных, как то:
- динамика изменения цены на компонент
- отслеживание популярности компонента через отслеживание изменения количества в стоке
- инверсная задача: отслеживание опустошения складских запасов (чтобы те, кто запасся заранее знали когда из под полы можно начать приторговывать. #лопата #смеяться #шутка)
Скачать
Листинг исходника
https://github.com/iDoka/digikey-cool-stuff/blob/master/digikey-stock-watcher.php