PHP SDK: Сбор из JSON и работа с параметрами
Некоторые сайты получают товары из JSON API. Такой ответ обычно удобнее HTML: цена уже является числом, а поля имеют устойчивые имена. Посмотрите сетевые запросы страницы и проверьте, доступен ли ответ с сервера парсинга.
Пример ответа источника
{"items":[{"id":"A-001","title":"Ремень","price":1500.5}],"next":null}
В этом примере next содержит URL следующей страницы или null. Это условный контракт источника: названия полей нужно заменить реальными.
Пример сценария
<?php
function run(\Sdk\Context $ctx): void
{
$url = (string) $ctx->param('api_url', '');
if ($url === '') {
$ctx->abort('Укажите api_url');
}
$seen = [];
$page = 0;
while ($url !== '') {
if (isset($seen[$url]) || $page >= 100) {
$ctx->abort('Повтор страницы или предел обхода');
}
$seen[$url] = true;
$response = $ctx->http()->withHeaders(['Accept' => 'application/json'])->get($url);
if (!$response->ok()) {
$ctx->abort('API источника ответил HTTP ' . $response->status);
}
$data = $response->json();
if (!isset($data['items']) || !is_array($data['items'])) {
$ctx->abort('В ответе отсутствует список items');
}
foreach ($data['items'] as $item) {
if (!isset($item['id'])) {
$ctx->log('Пропущена запись без id', [], 'warning');
continue;
}
$ctx->emit([
'sku' => (string) $item['id'],
'name' => $item['title'] ?? null,
'price' => $item['price'] ?? null,
], (string) $item['id']);
}
$page++;
$ctx->log('Получена страница API', ['page' => $page, 'items' => count($data['items'])]);
$next = $data['next'] ?? null;
$url = is_string($next) && $next !== '' ? $ctx->url()->absolutize($response->finalUrl, $next) : '';
}
}
Если источник возвращает курсор, а не URL, передавайте его в следующий запрос так, как требует этот источник. Не заменяйте курсор числом страницы.
Параметры запуска
$ctx->param('name', $default) читает один параметр, $ctx->params() возвращает весь объект. Адрес каталога, ограничение объёма проверки и выбор категории удобно передавать параметрами. Тогда для другого запуска не потребуется менять код.
Не добавляйте пароли в сообщения журнала. Для доступа к секрету источника предусмотрен $ctx->credential('name'); имя должно соответствовать настроенным данным доступа. API-ключ управления Akmelo не является ключом API сайта-источника.