К содержимому

Документация

Журнал, прогресс и безопасный повтор на Python

ctx.log(message, context, level) добавляет сообщение в журнал прогона; progress(done, total, label, percent) показывает этап; metric(name, value) записывает числовую метрику. Они доступны и при пробе, и при рабочем запуске. Не подменяйте журнал вызовом print: используйте структурированные события SDK.

def run(ctx):
    urls = ctx.param('urls', [])
    if not isinstance(urls, list):
        ctx.abort('Укажите список адресов')
    ctx.log('Начинаем обход', {'pages': len(urls)})
    processed = 0
    for url in urls:
        if ctx.cancelled():
            ctx.abort('Сбор остановлен пользователем')
        response = ctx.http().get(str(url))
        if not response.ok():
            ctx.fail('HTTP ' + str(response.status))
        processed += 1
        ctx.metric('pages_processed', 1)
        ctx.progress(processed, len(urls), 'Загрузка страниц')
    ctx.log('Обход завершён', {'processed': processed})

Если total неизвестен, передайте None. Не придумывайте точный процент и не показывайте 100% до обработки всех записей. Диагностические сообщения должны объяснять действие или причину пропуска, без паролей, токенов, текста личной почты и содержимого приватных документов.

Состояние между запусками

def run(ctx):
    state = ctx.state()
    number = int(state.get('next_page', 1))
    url = ctx.url().with_param(ctx.param('catalog_url'), 'page', number)
    response = ctx.http().get(url)
    if not response.ok():
        ctx.fail('HTTP ' + str(response.status))
    cards = response.dom().qa('.product-card')
    for card in cards:
        sku = card.attr('data-sku')
        if sku:
            ctx.emit({'sku': sku, 'name': card.text()}, sku)
    ctx.flush()
    if cards:
        state.set('next_page', number + 1)

Состояние хранит небольшой курсор, а не каталог. flush() отправляет пачку записей в конвейер и не является подтверждением окончательного успешного сохранения. Поэтому после сбоя страница может быть обработана снова. Стабильный ключ делает это безопаснее. Для полного обновления каталога продумайте, когда курсор возвращается к началу; не храните единственный возрастающий номер навсегда.

state имеет общие пределы числа ключей и размера значения, а проба и рабочий запуск могут иметь разный контекст сохранения. Проверяйте ожидаемое поведение на тестовом запуске. KeyValue описывает методы.