При парсинге различных сервисов через их API, ответы часто приходят в виде JSON. В А-Парсере есть инструмент для работы с ним: tools.parseJSON. Но, если возникает задача сделать дополнительные действия с данными внутри объекта (например отфильтровать, извлечь регулярным выражением часть данных или уникализировать по какой-то переменной), то использование данного инструмента может вызывать трудности из-за необходимости писать шаблоны (порой довольно сложные) с помощью Template Toolkit в Формате результата или других полях. Поэтому, ниже будет рассказано, как написать универсальный парсер JSON, используя JavaScript парсеры.
Разберем следующую задачу.
Есть список пользователей на GitHub. Нужно отфильтровать и оставить только тех пользователей, у которых кол-во подписчиков >100. При этом, местоположение каждого пользователя должно быть уникально.
Узнать кол-во подписчиков пользователя GitHub можно с помощью простого API запроса:
В ответе будет JSON, внутри которого в переменной followers указано количество подписчиков, а в location - местоположение.
Стандартными средствами А-Парсера данную задачу можно решить так:
Но, используя JS парсеры, эту задачу можно решить значительно проще. Напишем небольшой парсер, который:
Для удобства и возможности задавать различные параметры (юзер-агент, заголовки и т.д.) используется
Net::HTTP.
Готовый парсер доступен в каталоге: https://a-parser.com/resources/288/
Используем этот парсер для решения нашей задачи:
Теперь полученный JSON десериализуется не в формате результата, после того, как отработали все составные части пресета (Порядок обработки запросов), а непосредственно на этапе работы используемого парсера. И это позволяет использовать переменные из полученного обьекта, как стандартные.
Как видно на скриншоте, теперь можно легко применить фильтр, выбрав в нем Custom template и указав нужную переменную.
Уникализацию так же можно использовать, но тут немного сложнее, т.к. в уникализации нет возможности задать Custom template. Поэтому сначала используется Конструктор результатов, который по сути просто копирует в новую переменную содержимое $json.location. И уже эта переменная доступна для уникализации.
Таким образом поставленная задача решается в полном обьеме.
Пример результата:
Рассматриваемая задача является довольно простой и выбрана для демонстрации возможностей. Получившийся парсер является универсальным, его можно использовать и для более сложных сценариев, в которых ключевой является необходимость "на лету" обрабатывать данные из получаемых JSON-объектов.
Разберем следующую задачу.
Есть список пользователей на GitHub. Нужно отфильтровать и оставить только тех пользователей, у которых кол-во подписчиков >100. При этом, местоположение каждого пользователя должно быть уникально.
Узнать кол-во подписчиков пользователя GitHub можно с помощью простого API запроса:
Код:
https://api.github.com/users/{username}
Стандартными средствами А-Парсера данную задачу можно решить так:
- Используется
Net::HTTP - В указанный выше урл подставляется имя пользователя
- В формате результата пишется шаблон, который
- десериализует полученный JSON
- извлекает нужную переменную
- проверяет ее значение и фильтрует
Но, используя JS парсеры, эту задачу можно решить значительно проще. Напишем небольшой парсер, который:
- сделает запрос по указанной ссылке;
- проверит валидность ответа;
- вернет json-объект, к переменным которого можно обращаться напрямую в пресете.
Код:
*parse(set, results) {
let resp = yield this.parser.request('Net::HTTP', this.conf.Net_HTTP_preset, set.query);
if(!resp.info.success) {
this.logger.put('Error open page');
results.success = 0;
} else {
this.utils.updateResultsData(results, resp.data);
try {
results.json = JSON.parse(resp.data);
results.success = 1;
} catch(e) {
this.logger.put('Error parsing JSON response: ' + e.message);
results.success = 0;
}
}
return results;
}
Net::HTTP.Готовый парсер доступен в каталоге: https://a-parser.com/resources/288/
Используем этот парсер для решения нашей задачи:
Теперь полученный JSON десериализуется не в формате результата, после того, как отработали все составные части пресета (Порядок обработки запросов), а непосредственно на этапе работы используемого парсера. И это позволяет использовать переменные из полученного обьекта, как стандартные.
Как видно на скриншоте, теперь можно легко применить фильтр, выбрав в нем Custom template и указав нужную переменную.
Уникализацию так же можно использовать, но тут немного сложнее, т.к. в уникализации нет возможности задать Custom template. Поэтому сначала используется Конструктор результатов, который по сути просто копирует в новую переменную содержимое $json.location. И уже эта переменная доступна для уникализации.
Таким образом поставленная задача решается в полном обьеме.
Пример результата:
Получившийся пресет доступен под спойлером:
Код:
eJyNVm1T4zYQ/iuuhhuHnjHJh36ob9oZelfaMgxQ4D7FGUaxN45AkVxJJqQZ//fu
+j0md1N/AGv30e6zr86eOW5f7J0BC86yaL5nefXOInYDLor+fHy8864ebm88eOOb
XAILWM6NBUPoObt6iKIOGEWEREQKK15Ix4I9c7sc0NhKSAcGVWidNBGbf/CerVbh
Skupt2jP+7BAfQ18rG/9ioJXLgt6n02neNK5E1rh0YKyrOwdFEr8U8DQgdQJr8BB
o2yMWmeEyjrpH1IvuWSRMwWUi0VrwF5qs+Fk51pnQkXeST4LK8KSzoF3wzcwkCo8
Bt5lG8xA0wUYeNcNpQNrtSiOVUfePvBXeNR12vqY7CWeyC0qTlLugLRonnhOTkP3
hglnPE0F2eOyDoDK1Af1tc5SxJRGLL4aAfbS6A2KHFQGSLhrg5+ztXO5jc7PeS7C
TLh1sQwTvTkvqAPOTyowW7S5/Ls2yKIVlxYCZjGOS44s07FGYJG50+a2qifK90yr
Cymv4RVkD6vs/1YImaK7ixVe+qu5eBxy+85G2cU+dPUKZmuQQw9KNda5TcwLQN6l
6oYkG22gM9B4buzi8OSgUkT2lbrIe9EBwYNqDIR7ZnVhEvQ3nwZns6Abj7Y/aDrw
ZtPtBjJ4q9zR/4hNwo+n7bFuc1VIiXBNNewmYVGiiUSrlchuMQVGpNAyKtQjboJb
9VnTlLvOAhb6vu++C9sUkg59IsaXP1cukFe3CJCJlvbqoU5JbgQS+4kIb7AWQ6+N
yYRL+fX+eqhhfcfiIdNprC42IllzEatnvVOg8xjhmNAvW66yWElRbLFeseKFdUK9
gJSwBoPX5Jav7TpWwEWmSLIWihvBEbrR6gWvrM3y5ymaKIQVS67gX1Sd2RdGzBxk
GrueilbNDI2OpRjhLecqhbRdJpTtZll2G3Z/dGVG+xJ78Nne1WjK7newtJrPSHJG
AtwjSCGR3Fqvvu/tY+Xhg5XGZVckOC6T01ZIj1sLGza1oVp5vwy19GB32GpR+bNw
Gs784FDdNHA0vkbPSnIXefP3CnrmPnW1H3h+9VHRy2dInL8IvoXGNccJfc+3XvW+
eI8cicrjXJ/qRYkRnVSDVfM4hGJenyivT/VHELFNkvweV37q30cZBVy9fCmhSeko
BXN/ZB7jmvu4TJd6qd8oyP6L2wAWg9AWjd8yVvXLj1VrTRAXtDEeFBmnhuQ5MtkJ
kGnNse7H0ACOknWT3icSqAC0HsIR08DDP2G1yE6RRuxiJ1aTH8h6KNRKh7ZIErCH
/ru04AczQ5d5ge5+N0YbT+N29HKegX/66WixWoPIfTpAlB4udjjqpHBC4t+cvovN
wvqC/TJpDFYpykNqobFLZ3ZDixRcy4J6BClUU1Zn+5tWjpOfjVClh+sjWU/gXaa+
ky3yjL9Y6p9hRADHGn96+N5HD8INOsJE/j860zGdQWrbtqpvusKo1kDfeCWjNdXs
BhbNyv8A5BBIvA==
Рассматриваемая задача является довольно простой и выбрана для демонстрации возможностей. Получившийся парсер является универсальным, его можно использовать и для более сложных сценариев, в которых ключевой является необходимость "на лету" обрабатывать данные из получаемых JSON-объектов.