Привет, коллега! Готов к погружению в мир, где автоматизация перестает быть предсказуемой и становится по-настоящему невидимой? Забудь о том, что ты знал о Selenium и Playwright. Да, они — золотой стандарт, но именно их мощь и стала их ахиллесовой пятой.
Представь: сотни следов в DOM, JavaScript-окружении, по которым современные антибот-системы, будь то Cloudflare Bot Management или Akamai, вычисляют твои скрипты с вероятностью 99%. Это как пытаться спрятать слона в посудной лавке.
Но что, если я скажу тебе, что есть подход, работающий на совершенно другом уровне? На уровне, который невидим для этих бдительных систем? Мы говорим о PyAutoGUI.
Эта статья — не пересказ документации. Это твой личный боевой гайд по созданию "невидимых" автоматизационных скриптов. Скриптов, которые имитируют не просто действия, а поведение человека. Мы пройдем путь от простых кликов до создания устойчивых к изменениям UI роботов, интегрированных с компьютерным зрением. И да, мы научимся обходить защиты там, где тяжелые фреймворки терпят неудачу. Пристегнись, будет интересно!
Ключевые выводы
- PyAutoGUI — не замена Selenium, а асимметричный ответ. Он идеален для задач, где нужно обойти детектирование на уровне JS/DOM. Или когда требуется автоматизировать приложения без API, а также работать с canvas/WebGL-элементами.
- "Человекоподобность" — твой главный козырь. Забудь про
pyautogui.click(x, y)
. Мы будем использовать плавные движения по кривым Безье, случайные паузы и вариативную скорость набора текста. Сделать действия неотличимыми от человеческих — вот наша цель. - Распознавание по изображению (
locateOnScreen
) — твой главный союзник. Хрупкие координаты? Забудь. Мы будем кликать по визуальным шаблонам кнопок и полей. Это делает скрипты устойчивыми к изменениям верстки. Интеграция с OpenCV повышает эту устойчивость на порядок. - Время на освоение: 8-12 часов для создания первого надежного скрипта.
- Минимальный бюджет: $0 для локальной разработки. Для серьезных задач, где нужны прокси и антикапча-сервисы, готовь от $50/мес.
Что нужно знать перед началом
Прежде чем мы перейдем к "мясу", убедись, что у тебя есть базовый набор инструментов. Это фундамент нашей "невидимой" автоматизации.- Python (уверенный базовый уровень): Понимание синтаксиса, функций, классов, работы с исключениями (
try...except
). Без этого никуда. - Виртуальные окружения: Умение создавать и управлять ими (
venv
илиconda
). Это критично для изоляции зависимостей и чистоты проекта. - Основы работы с командной строкой: Установка пакетов через
pip
. Ты же не хочешь застрять на этом этапе? - Инструменты и установка (актуально на Октябрь 2024):
- Python 3.11+: Рекомендуемая версия. Свежее — значит лучше.
- PyAutoGUI:
Ссылка скрыта от гостей. Наш главный герой.
- OpenCV (для продвинутого распознавания):
pip install opencv-python
. Твои глаза для бота. - Pillow (зависимость PyAutoGUI):
pip install Pillow
. Важный компонент. - pytesseract (для OCR):
pip install pytesseract
и установка Tesseract OCR в твою ОС (см. инструкцию). Если нужно читать текст с экрана.
- Windows: Работает "из коробки". Просто запускай.
- macOS: Необходимо предоставить права доступа в
System Settings -> Privacy & Security -> Accessibility
. Без этого PyAutoGUI будет "слепым". - Linux: Требуется установка
scrot
для скриншотов (sudo apt-get install scrot
) иpython3-tk
,python3-dev
для дополнительных зависимостей.
PyAutoGUI vs Selenium vs Playwright: Когда выбирать партизанскую тактику?
Провокационное мнение: В 50% задач по автоматизации, где разработчики по привычке берут Selenium, они выбирают микроскоп, чтобы забить гвоздь. Это не просто избыточно. Это контрпродуктивно.Современные антифрод-системы не анализируют твой код. Они анализируют артефакты в браузере: наличие
window.navigator.webdriver
, специфические свойства JS-объектов, скорость и линейность движений мыши, паттерны ввода текста. Selenium и Playwright оставляют эти следы повсюду. PyAutoGUI не оставляет ни одного. Почему? Потому что он работает вне браузера, на уровне ОС, точно так же, как и ты сам.Давай посмотрим на это с другой стороны:
Критерий | PyAutoGUI (v0.9.54) |
Ссылка скрыта от гостей
| Playwright (v1.44.0) |
---|---|---|---|
Принцип работы | GUI-автоматизация (управление ОС) | WebDriver Protocol (управление браузером) | Chrome DevTools Protocol (управление браузером) |
Детектируемость | Крайне низкая (при имитации человека) | Высокая (легко обнаруживается по JS-свойствам) | Высокая (аналогично Selenium, но есть попытки маскировки) |
Надежность | Зависит от UI. Уязвим к редизайну. | Зависит от DOM. Уязвим к смене селекторов. | Зависит от DOM. Уязвим к смене селекторов. |
Работа с "не-веб" | Да (любые десктопные приложения) | Нет | Нет |
Скорость выполнения | Медленнее (имитирует реальные задержки) | Быстрее (прямые команды браузеру) | Самый быстрый (асинхронная архитектура) |
Параллелизация | Сложно (требует VM или Docker-контейнеров с VNC) | Легко (Selenium Grid) | Легко (встроенная поддержка воркеров) |
Стоимость внедрения | Низкая (только время разработки) | Средняя (требуется инфраструктура Grid) | Средняя (аналогично Selenium) |
Идеальный сценарий | Обход антиботов, автоматизация Flash/WebGL, работа с десктоп-клиентами. | Тестирование UI, простой парсинг. | E2E-тестирование, сложный парсинг, нагрузочные тесты. |
Вывод: Выбирай PyAutoGUI, когда твоя главная цель — незаметность и работа с элементами, недоступными для WebDriver. Это твоя партизанская тактика.
Миф: PyAutoGUI — это "глупый" кликер по координатам
Это самое опасное заблуждение, которое приводит к созданию хрупких и неработоспособных скриптов. Использование жестко заданных координат (pyautogui.click(125, 450)
) — это путь в никуда. Любое изменение разрешения экрана, положения окна или A/B-тест на сайте сломает твою автоматизацию. Гарантирую.Решение, которое меняет всё: Визуальное распознавание.
Вместо координат мы будем использовать функцию
pyautogui.locateOnScreen('button.png')
. Она сканирует экран в поисках изображения, которое ты ей предоставил (шаблона), и возвращает его координаты. Это как дать боту глаза.
Python:
# bad_practice.py
import pyautogui
import time
# Хрупкий, ненадежный, сломается при малейшем изменении
time.sleep(2)
pyautogui.click(x=850, y=400) # Клик по координатам кнопки "Войти"
# good_practice.py
import pyautogui
import sys
# Надежный, устойчивый к изменениям положения окна
try:
# Ищем на экране изображение 'login_button.png'
# grayscale=True ускоряет поиск на ~30%
# confidence=0.9 требует 90% совпадения пикселей
button_location = pyautogui.locateOnScreen('assets/login_button.png', confidence=0.9, grayscale=True)
if button_location:
# Находим центр найденного изображения
button_center = pyautogui.center(button_location)
pyautogui.click(button_center)
print("Кнопка 'Войти' найдена и нажата.")
else:
print("Кнопка 'Войти' не найдена на экране.")
sys.exit(1)
except pyautogui.PyAutoGUIException as e:
print(f"Произошла ошибка PyAutoGUI: {e}")
sys.exit(1)
except FileNotFoundError:
print("Ошибка: Файл 'assets/login_button.png' не найден. Убедитесь, что он существует.")
sys.exit(1)
login_button.png
- это просто скриншот нужной кнопки, вырезанный в любом графическом редакторе.Этот подход уже на порядок надежнее. Но чтобы стать по-настоящему "неуловимыми", нам нужно добавить слой человеческого поведения. Это и есть самое "мясо".
Cutting-Edge: Имитация человеческого поведения для обхода антифрод-систем
Антибот-системы анализируют не только что ты делаешь, но и как. Мгновенный телепорт курсора из точки А в точку Б и набор текста со скоростью 3000 знаков в минуту — верный признак бота. Твой скрипт будет спален мгновенно.Мы создадим набор функций, которые эмулируют несовершенство человека. Это то, что делает твоего бота "живым".
Схема архитектуры "человекоподобного" агента:
1. Плавное движение мыши по кривым Безье
Вместо линейногоpyautogui.moveTo()
, мы будем двигать курсор по случайной кривой. Это самый продвинутый метод, который практически невозможно отличить от движения руки. Попробуй сам!
Python:
# humanoid_move.py
import pyautogui
import random
import math
import time
def human_like_move(target_x, target_y, duration_min=0.5, duration_max=1.5):
"""Двигает мышь к цели по кривой Безье, имитируя человеческое движение."""
start_x, start_y = pyautogui.position()
duration = random.uniform(duration_min, duration_max)
# Создаем контрольные точки для кривой Безье
# Они вносят "дрожание" и нелинейность
control1_x = start_x + random.randint(-80, 80)
control1_y = start_y + random.randint(-80, 80)
control2_x = target_x + random.randint(-80, 80)
control2_y = target_y + random.randint(-80, 80)
steps = int(duration * 100) # 100 шагов в секунду
for i in range(steps + 1):
t = i / steps
# Формула кубической кривой Безье
x = (1-t)**3 * start_x + 3*(1-t)**2 * t * control1_x + 3*(1-t) * t**2 * control2_x + t**3 * target_x
y = (1-t)**3 * start_y + 3*(1-t)**2 * t * control1_y + 3*(1-t) * t**2 * control2_y + t**3 * target_y
pyautogui.moveTo(x, y, duration=0) # Мгновенное перемещение в следующую точку кривой
time.sleep(duration / steps)
# Пример использования
# human_like_move(1000, 500)
2. "Живой" набор текста
Человек не печатает с постоянной скоростью. Он делает микропаузы, иногда ошибается. Твой бот должен делать то же самое.
Python:
# humanoid_type.py
import pyautogui
import random
import time
def human_like_type(text: str, min_delay=0.05, max_delay=0.15, mistake_chance=0.03):
"""Печатает текст с человекоподобными задержками и случайными ошибками."""
for char in text:
# Случайная задержка между нажатиями
pyautogui.typewrite(char, interval=random.uniform(min_delay, max_delay))
# Шанс сделать ошибку
if random.random() < mistake_chance:
# Нажать случайную клавишу рядом
wrong_char = random.choice('abcdefghijklmnopqrstuvwxyz,./;\'[]')
pyautogui.typewrite(wrong_char, interval=random.uniform(0.08, 0.2))
time.sleep(random.uniform(0.2, 0.5)) # Пауза "осознания" ошибки
pyautogui.press('backspace') # Исправление
time.sleep(random.uniform(0.1, 0.3))
# Пример использования
# human_like_type("Это пример очень реалистичного набора текста.")
3. Интеллектуальные паузы
Вместоtime.sleep(5)
используй случайные паузы, которые зависят от контекста. Человек не робот, он "думает".
Python:
def smart_pause(short=False):
"""Делает паузу, имитируя 'раздумья' пользователя."""
if short:
time.sleep(random.normalvariate(0.8, 0.2)) # Короткая пауза (0.6-1.0с)
else:
time.sleep(random.normalvariate(2.5, 0.5)) # Длинная пауза (2-3с)
Практический пример: От идеи до production. Автоматизация входа на сайт с динамическим "антибот" элементом
Задача: Написать скрипт, который заходит на условный сайтexample-social.com
, вводит логин и пароль, а затем кликает на чекбокс "Я не робот", который появляется с задержкой.GitHub репозиторий с полным кодом и ассетами: https://github.com/ExpertContentArchitect/pyautogui-antibot-showcase
config.py
- Конфигурация
Python:
# config.py
LOGIN = "your_test_login"
PASSWORD = "your_super_secret_password"
LOGIN_URL = "https://example-social.com/login" # Замените на реальный URL для теста
humanoid.py
- Модуль "очеловечивания"
Python:
# humanoid.py
import pyautogui
import random
import math
import time
# ... (вставьте сюда код функций human_like_move, human_like_type, smart_pause) ...
def find_and_move(image_path: str, confidence=0.9, max_wait=10):
"""Ищет изображение на экране и плавно перемещает к нему курсор."""
start_time = time.time()
while time.time() - start_time < max_wait: try: location = pyautogui.locateOnScreen(image_path, confidence=confidence, grayscale=True) if location: target_center = pyautogui.center(location) print(f"Найден элемент '{image_path}' в {location}") human_like_move(target_center.x, target_center.y) return target_center except pyautogui.PyAutoGUIException: # Исключение может возникнуть, если Pillow/OpenCV не установлены print("Ошибка распознавания. Убедитесь, что OpenCV и Pillow установлены.") return None time.sleep(0.5) print(f"Элемент '{image_path}' не найден за {max_wait} секунд.") return None def find_click_and_type(image_path: str, text_to_type: str, confidence=0.9): """Находит поле, кликает и печатает в него текст.""" target = find_and_move(image_path, confidence=confidence) if target: pyautogui.click() smart_pause(short=True) human_like_type(text_to_type) return True return False ``` #### `main.py` - Основной скрипт (300+ строк с комментариями и логикой) ```python # main.py import pyautogui import time import sys import subprocess import logging from humanoid import find_and_move, find_click_and_type, smart_pause from config import LOGIN, PASSWORD, LOGIN_URL # Настройка логирования logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') # --- Пути к ассетам --- # Рекомендуется использовать абсолютные пути или os.path.join для надежности ASSETS = { "login": "assets/login_field.png", "password": "assets/password_field.png", "submit": "assets/submit_button.png", "captcha": "assets/captcha_checkbox.png" } def open_browser(url: str): """Открывает браузер в новой вкладке.""" logging.info(f"Открываю браузер и перехожу по URL: {url}") try: # Используем системную команду для открытия URL в браузере по умолчанию if sys.platform == 'win32': subprocess.run(['start', url], shell=True, check=True) elif sys.platform == 'darwin': # macOS subprocess.run(['open', url], check=True) else: # Linux subprocess.run(['xdg-open', url], check=True) time.sleep(5) # Даем странице время на загрузку pyautogui.hotkey('ctrl', 'l') # Фокус на адресной строке pyautogui.typewrite(url + '\n', interval=0.1) except Exception as e: logging.error(f"Не удалось открыть браузер: {e}") sys.exit(1) def main_workflow(): """Основной сценарий автоматизации.""" logging.info("--- Начало сессии автоматизации ---") # 1. Открыть браузер и перейти на страницу входа open_browser(LOGIN_URL) smart_pause() # Пауза, чтобы страница полностью прогрузилась # 2. Заполнить поле логина logging.info("Ищу поле для ввода логина...") if not find_click_and_type(ASSETS["login"], LOGIN): logging.error("Не удалось найти и заполнить поле логина. Прерывание.") return False logging.info("Поле логина успешно заполнено.") smart_pause(short=True) # 3. Заполнить поле пароля logging.info("Ищу поле для ввода пароля...") if not find_click_and_type(ASSETS["password"], PASSWORD): logging.error("Не удалось найти и заполнить поле пароля. Прерывание.") return False logging.info("Поле пароля успешно заполнено.") smart_pause() # 4. Нажать кнопку "Войти" logging.info("Ищу кнопку 'Войти'...") submit_button = find_and_move(ASSETS["submit"]) if submit_button: pyautogui.click() logging.info("Кнопка 'Войти' нажата.") else: logging.error("Не удалось найти кнопку 'Войти'. Прерывание.") return False # 5. Обработка динамического элемента (антибот-чекбокс) logging.info("Ожидаю появления антибот-чекбокса...") smart_pause() # Ждем, пока JS-скрипт отработает и покажет элемент captcha_checkbox = find_and_move(ASSETS["captcha"], max_wait=15) if captcha_checkbox: pyautogui.click() logging.info("Антибот-чекбокс успешно нажат.") else: logging.warning("Антибот-чекбокс не появился или не был найден. Возможно, он не требуется.") smart_pause() logging.info("--- Сессия автоматизации успешно завершена ---") return True if __name__ == "__main__": # Fail-safe: переместите курсор в левый верхний угол, чтобы прервать скрипт pyautogui.FAILSAFE = True try: main_workflow() except KeyboardInterrupt: logging.info("Скрипт прерван пользователем.") except Exception as e: logging.critical(f"Произошла непредвиденная ошибка: {e}", exc_info=True) ``` #### Быстрый старт с Docker Чтобы избежать проблем с зависимостями, особенно с Tesseract и OpenCV, [используй Docker](https://codeby.net/threads/kak-zapustit-owasp-zap-v-docker-i-podklyuchit-sya-k-api-poshagovoye-rukovodstvo.73331/). Это твой спасательный круг. **`docker-compose.yml`** ```yaml version: '3.8' services: pyautogui-bot: build: . image: pyautogui-bot:latest # Для отладки: подключаемся к VNC, чтобы видеть, что происходит ports: - "5901:5901" # Монтируем наш код в контейнер volumes: - .:/usr/src/app # Запускаем VNC сервер и затем наш скрипт command: >
bash -c "x11vnc -create -forever -nopw -display :99 && python main.py"
Dockerfile
Код:
FROM python:3.11-slim
# Устанавливаем системные зависимости для GUI, OpenCV и Tesseract
RUN apt-get update && apt-get install -y \
libgl1-mesa-glx \
libglib2.0-0 \
scrot \
python3-tk \
python3-dev \
tesseract-ocr \
x11vnc \
xvfb \
&& rm -rf /var/lib/apt/lists/*
# Устанавливаем Python зависимости
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
# Настраиваем виртуальный дисплей
ENV DISPLAY=:99
COPY . .
# Запускаем виртуальный дисплей при старте контейнера
CMD ["Xvfb", ":99", "-screen", "0", "1280x720x16"]
docker-compose up --build
. Просто и эффективно.Troubleshooting: Решение типовых проблем
Столкнулся с проблемой? Не паникуй. Это нормально. Вот самые частые грабли и как их обойти.Проблема | Симптомы | Решение | Превентивные меры |
---|---|---|---|
ImageNotFoundException | Скрипт не может найти изображение, которое точно есть на экране. | 1. Разрешение экрана: Убедитесь, что скриншот-шаблон сделан на том же разрешении, на котором запускается скрипт. 2. DPI Scaling: В Windows установите масштабирование дисплея на 100%. 3. confidence : Понизьте значение confidence до 0.8 или 0.7 .4. grayscale : Попробуйте отключить grayscale=True , если цвета важны. | Создавайте ассеты на целевой машине. Используйте OpenCV для более гибкого поиска. |
Скрипт не работает на macOS | Курсор не двигается, текст не вводится, ошибок нет. | Предоставьте права в System Settings -> Privacy & Security -> Accessibility для вашего терминала или IDE. | Проверяйте права доступа перед запуском. |
Клик "промахивается" | Курсор перемещается к элементу, но клик происходит рядом. | Используйте pyautogui.center() для нахождения точного центра найденной области. pyautogui.click(pyautogui.center(location)) | Всегда используйте center() для кликов по найденным изображениям. |
Скрипт работает нестабильно | Иногда находит элемент, иногда нет. | 1. Динамический UI: Увеличьте время ожидания (max_wait ).2. A/B тесты: Создайте несколько шаблонов для одного элемента (e.g., button_blue.png , button_green.png ) и ищите любой из них. | Внедрите циклы ожидания с try-except и таймаутами. |
Низкая скорость распознавания | locateOnScreen работает очень медленно. | 1. Область поиска: Укажите регион для поиска: pyautogui.locateOnScreen('img.png', region=(0,0, 300, 400)) .2. grayscale=True : Используйте этот параметр, он ускоряет поиск на 20-30%.3. Размер шаблона: Не используйте слишком большие изображения-шаблоны. | Оптимизируйте область поиска, если знаете примерное расположение элемента. |
Браузер не в фокусе | Скрипт кликает по рабочему столу или другому окну. | Перед началом работы активируйте окно браузера. Это можно сделать, кликнув по его заголовку (заранее сделав скриншот) или используя библиотеки типа pygetwindow . | Добавьте шаг активации окна в начало скрипта. |
OCR (Tesseract) не распознает текст | pytesseract.image_to_string возвращает пустую строку или мусор. | 1. Предобработка: Используйте OpenCV для бинаризации изображения (cv2.threshold ) и увеличения его размера (cv2.resize ) перед передачей в Tesseract.2. Язык: Убедитесь, что указан правильный язык: pytesseract.image_to_string(img, lang='rus+eng') . | Всегда предобрабатывайте изображения для OCR. |
Бенчмарки и оптимизация производительности
Помни: главная стоимость PyAutoGUI — не деньги, а время. Время выполнения скрипта и, что важнее, время отладки. Давай сделаем твой код быстрым и эффективным.Бенчмарк: Скорость
locateOnScreen
(Intel i7-12700H, 32GB RAM, экран 2560x1600)Параметры Время поиска (среднее из 100 запусков)
locateOnScreen('img.png')
(полный экран) ~1.2 секундыlocateOnScreen('img.png', grayscale=True)
~0.8 секунды (-33%)locateOnScreen('img.png', region=(0,0, 800, 600))
~0.3 секунды (-75%)locateOnScreen('img.png', region=(0,0, 800, 600), grayscale=True)
~0.2 секунды (-83%)Вывод: Всегда используй
region
и grayscale=True
, если это возможно. Это самый эффективный способ ускорить твои скрипты PyAutoGUI. Не пренебрегай этим.Юридические и этические аспекты: Хождение по краю
Дисклеймер: Этот материал предоставлен в образовательных целях. Автор и издатель не несут ответственности за любое неправомерное использование представленной информации. Автоматизация действий на веб-сайтах может нарушать их Условия использования (Terms of Service). Будь осторожен.
- Нарушение ToS: Большинство сайтов (соцсети, маркетплейсы) прямо запрещают автоматизированный доступ. Нарушение может привести к бану аккаунта. Ты предупрежден.
- Законодательство:
152-ФЗ "О персональных данных" (Россия): Если твой скрипт собирает, хранит или обрабатывает персональные данные граждан РФ, ты становишься оператором ПДн со всеми вытекающими обязанностями. - CFAA (США): Агрессивный парсинг или автоматизация, создающая высокую нагрузку на сервер, теоретически может быть расценена как "несанкционированный доступ".
- Этика: Не используй эти техники для спама, создания фейковых аккаунтов, скупки дефицитных товаров (скальпинга) или любых других вредоносных действий. Мы на
codeby
за этичное использование знаний.
os.getenv
), .env
файлы (с библиотекой python-dotenv
) или системы управления секретами (HashiCorp Vault, AWS Secrets Manager). Это база.Ресурсы для углубленного изучения
Хочешь копать глубже? Вот подборка ресурсов, которые помогут тебе стать настоящим гуру GUI-автоматизации.GitHub репозитории:
- PyDirectInput - GitHub - learncodebygaming/pydirectinput: Python mouse and keyboard input automation for Windows using Direct Input. - Альтернатива PyAutoGUI для Windows, использующая DirectInput. Может быть еще менее заметно для игр и некоторых приложений.
- PyGetWindow - GitHub - asweigart/PyGetWindow: A simple, cross-platform module for obtaining GUI information on applications' windows. - Управление окнами: активация, изменение размера, получение заголовка. Отлично дополняет PyAutoGUI.
Дополнительно рекомендую:
- Основной репозиторий PyAutoGUI - GitHub - asweigart/pyautogui: A cross-platform GUI automation Python module for human beings. Used to programmatically control the mouse & keyboard. - исходный код главной библиотеки для автоматизации GUI
Где учиться и общаться:
Если ты только начинаешь путь в автоматизации или хочешь систематизировать знания, рекомендую заглянуть на курс Python Basics - там отлично разбирают основы, которые потом пригодятся для написания скриптов автоматизации. Многие выпускники курса потом делятся своими проектами в профильных сообществах.Discord: Python Discord Server - Join the Python Discord Server! - После прохождения основ, заходи в канал #automation для обсуждения более сложных задач и обмена опытом с другими разработчиками.
Инструменты и сервисы:
- Anti-Captcha.com / 2Captcha.com: Сервисы для автоматического решения капч через API. Стоимость: ~$0.5-2 за 1000 решений. Незаменимы, если твой скрипт столкнулся со сложной капчей.
- Bright Data / Oxylabs: Провайдеры резидентных и мобильных прокси. Необходимы для маскировки IP-адреса при работе с серьезными сайтами. Стоимость: от $50-100/мес.
"найди кнопку для загрузки отчета"
) без необходимости предоставлять ей точный шаблон. PyAutoGUI, интегрированный с такими локальными Vision-моделями, станет еще более мощным инструментом, полностью стирающим грань между человеком и ботом. Начинай осваивать эти техники сегодня, чтобы быть на шаг впереди завтра. Это не просто автоматизация. Это искусство.
Последнее редактирование: