Жизненный цикл Python-сценария
Создание и версия
Выберите сайт и Python при ручном создании сценария. У версии собственный исходный код; язык сохраняется у сценария. Создавайте новый сценарий для переноса кода с PHP/JavaScript, переписывая синтаксис и SDK-вызовы. Python не транслируется в JavaScript и не получает его глобальные объекты.
def title_from_card(card):
node = card.q('.title')
return node.text() if node is not None else ''
def run(ctx):
url = ctx.param('catalog_url', '')
if not url:
ctx.abort('Укажите адрес каталога')
response = ctx.http().get(url)
if not response.ok():
ctx.fail('HTTP ' + str(response.status))
for card in response.dom().qa('.product-card'):
sku = card.attr('data-sku')
if sku:
ctx.emit({'sku': sku, 'name': title_from_card(card)}, sku)
Вспомогательные функции разрешены. run получает один ctx и не возвращает список записей. Для преобразования выгрузки можно использовать специальную точку входа.
Проверка и пробный прогон
Проверка кода выполняется тем же изолированным Python-валидатором, который проверяет исходник перед запуском. Она выявляет синтаксис, недопустимые импорты, структуру точки входа и запрещённые конструкции. Это не запуск HTTP и не проверка данных сайта.
После проверки выполните пробный прогон черновика. Он использует настоящий Python SDK и платформенные обработчики; записи показываются в предпросмотре и не заменяют рабочий каталог. Проверьте хотя бы пустой ответ, одну полную запись, отсутствие необязательного элемента, неуспешный HTTP и устойчивый ключ. Проба не является гарантией полноты большого каталога.
Публикация и расписание
Опубликуйте проверенную версию. Рабочий ручной запуск и расписание берут опубликованный код. Публикация сама не запускает сбор. Черновик остаётся доступен для пробы; предыдущую опубликованную версию можно вернуть. Расписание использует общую систему Akmelo: выбранный часовой пояс, конкурентность, лимиты и журнал работают независимо от языка. Python-код не должен организовывать собственный бесконечный планировщик.
Во время рабочего запуска ctx.emit() отдаёт записи в общий конвейер: схема полей, ключи, контроль качества, история изменений и последующие выгрузки применяются как обычно. Журнал запуска и журнал HTTP доступны на странице прогона. Python-исключение даёт ошибку прогона, а не молчаливый успех.
Среда, импорты и пакеты
Среда: CPython 3.13. Код синхронный: используйте def, обычные for/try/finally, словари и списки. async def, await, классы и обход ограничений через внутренние атрибуты не являются поддерживаемым способом написания сценария. Не используйте __import__, eval, exec, compile, open, прямую рефлексию или попытки загрузки собственного модуля.
Разрешённый набор стандартной библиотеки описан в справочнике среды. Сторонние пакеты вроде requests, pandas, BeautifulSoup и Playwright в пользовательском коде не устанавливаются. HTTP выполняет ctx.http(), HTML разбирает ctx.dom(), браузер запускает ctx.browser(), документы читает ctx.documents(). SDK внутри среды может использовать необходимые библиотеки; это не разрешает импортировать их из сценария.
Лимиты, время и завершение
Пределы кода, памяти, вычислительного времени и общего времени контролирует runner. Конкретные пределы запуска зависят от режима и настроек платформы; сценарий не может их повысить. Бесконечный цикл или перерасход памяти останавливает песочницу с ошибкой. Сетевые обращения, количество запросов, robots.txt, допустимые адреса и прокси проверяются на стороне платформы. Прямого выхода в сеть из процесса Python нет.
Для паузы используйте ctx.sleep(ms), где время в миллисекундах, а не time.sleep(). Ожидание учитывается в общем времени и подчиняется остановке. Не создавайте потоки/подпроцессы ради обхода лимитов. Стабильные ключи и контроль числа страниц важнее самостоятельных бесконечных повторов.
def run(ctx):
for page in range(1, 11):
if ctx.cancelled():
ctx.abort('Остановлено пользователем')
ctx.log('Страница', {'page': page})
ctx.progress(page, 10, 'Каталог')
ctx.abort() означает осознанную остановку, ctx.fail() означает ошибку. Непойманное исключение Python также завершает прогон ошибкой. Не перехватывайте все ошибки с пустым except: так теряется причина неполных данных. Если обрабатываете ожидаемую ошибку, запишите безопасное пояснение и решите явно, можно ли продолжать.
Буфер emit отправляется пачками, flush() отправляет текущую пачку. Отправленная пачка не означает, что весь прогон успешно сохранён. Состояние и повтор описаны в отдельной статье.
Агент и автономность
Для Python выберите агент с соответствующим runtime; браузерный профиль включается отдельно. Агент применяет подписанные определения из облака, а локальная панель показывает прогон и результаты. Во время отсутствия облака работают доступные локальные функции и заранее полученные настройки. Зеркалирование определяет, появятся ли записи в облаке. Отключение зеркалирования не удаляет локальные записи и не превращает облачную страницу в локальную панель агента.
При автономном сборе избегайте обязательных облачных AI-запросов. Готовое правило обработки сохраните в Python-коде, а реальную автономность проверяйте без воздействия на остальных пользователей.