---
title: "Формы: заполнение и отправка"
description: "chromedp формы: SetValue и SendKeys по типам полей, SetUploadFiles для файлов, Enter и Submit, механика form.submit без валидации, автозаполнение go-циклом."
course: "Chromedp в Go: автоматизация Chrome без Selenium"
url: "https://golangmaster.ru/courses/chromedp/lessons/12-formy/"
published: "2026-09-19"
updated: "2026-09-21"
minutes: 18
---

# Формы: заполнение и отправка

*Курс «Chromedp в Go: автоматизация Chrome без Selenium», урок 12 из 25. ~18 минут. Обновлено 21.09.2026. Источник: https://golangmaster.ru/courses/chromedp/lessons/12-formy/*

chromedp формы заполняет комбинацией SetValue, SendKeys и SetUploadFiles, а отправляет кнопкой, Enter или Submit: логин, регистрация, загрузка отчёта — половина задач автоматизации упирается в форму, и у способов отправки разная механика, которая прямо влияет на валидацию. Разберём автозаполнение go-программой по типам полей: селекты, чекбоксы, файлы, ошибки формы и цикл по десяткам однотипных форм.

Пятый урок дал базовые жесты: Click, SendKeys, SetValue, Clear. Отдельное поле он научил заполнять, но форма — это не пять полей по отдельности, а контракт: поля связаны валидацией, кнопка зависит от их состояния, а отправка запускает переход или XHR. Здесь у новичков собирается урожай странностей: SetValue на чекбоксе не включает галочку, Submit не вызывает обработчик формы, форма в цикле отправляется дважды, файл не грузится из-за пути. Всё это не баги библиотеки, а следствия механики, которую стоит разложить по полочкам один раз. В этом уроке — целая форма: какое действие выбрать для какого типа поля, как грузятся файлы, чем отличаются три способа отправки и как собрать цикл автозаполнения по сотне однотипных форм, чтобы он не падал на пятьдесят седьмой. База из пятого урока предполагается: механика SetValue с событиями input и change и правило «SendKeys не чистит поле» здесь используются, а не разбираются заново.

### chromedp формы: карта действий по типам полей

chromedp формы собирают из четырёх действий, и выбор определяется типом поля, а не вкусом. SetValue — рабочая лошадка для текстовых полей: логины, пароли, телефоны, даты без масок. Он ставит свойство value, возбуждает input и change, чистит поле сам и стоит куда меньше посимвольного набора. SendKeys остаётся для полей, где важен процесс набора: маски, посимвольная валидация, поля с подсказками, а также для Enter в поиске. Click обслуживает всё нажимаемое: кнопки, чекбоксы, радиокнопки, ссылки-переключатели — состояние переключателей через value не выставишь, там правит клик. SetUploadFiles — отдельное действие для input типа file, о нём ниже. Отправка — Click по кнопке, Submit или Enter, и разница между ними станет главной темой второй половины урока. Общий порядок не меняется с пятого урока: сначала WaitVisible на форму, потом действия по полям, потом отправка и ожидание узла нового состояния. Проверка результата через чтение Value тоже остаётся дешёвой страховкой: поле, которое сайт увидел, читается обратно с тем значением, что вы положили.

### Логин целиком: от ожидания до профиля

```go
err := chromedp.Run(ctx,
        chromedp.WaitVisible("#login-form"),
        chromedp.SetValue("#email", "ivan@example.com"),
        chromedp.SetValue("#password", "qwerty"),
        chromedp.Click("button[type=submit]"),
        chromedp.WaitVisible("#profile"),
)
```

WaitVisible дожидается формы, SetValue ставит значения с событиями input и change, которых хватает React и Vue, Click нажимает кнопку с настоящими событиями мыши, WaitVisible доказывает переход в личный кабинет. Ни одного Sleep: каждый шаг ждёт факт. Если сайт валидирует по клавиатуре, поля вместо SetValue берут Clear плюс SendKeys из пятого урока.

### Селекты, чекбоксы и радиокнопки

Три типа полей требуют внимания, потому что работают не так, как текстовые. Селект — самый дружелюбный: SetValue на нём ставит свойство value, и если среди опций есть такая, браузер её выбирает; события input и change уходят, фреймворк замечает выбор. Главное — совпадение значения: value опции не всегда равен её тексту, «Москва» может лежать в value как msk, поэтому значение подсматривают в разметке, а не копируют с экрана. Если совпадение не нашлось, выбор делают кликом: Click по селекту, Click по опции — медленнее, но честнее для сайтов с кастомными дропдаунами, где под видом селекта живёт собственный компонент из div-ов. Чекбокс — полная противоположность: его состояние живёт в свойстве checked, а value — это просто строка, которая уедет на сервер. SetValue на чекбоксе меняет value, дёргает события, но галочку не ставит — типичная ловушка, разбор ниже в интерактиве. Работает Click по самому инпуту или по связанному label. Радиокнопки — те же чекбоксы с общим именем: клик по элементу нужного варианта, второй клик по соседней кнопке группы переключает выбор. Проверка состояния читается Evaluate-выражением по checked — это чтение, а не подмена. Отдельно держите в голове нативные поля с типом date или number: их value живёт в служебном формате — дата как yyyy-mm-dd — и SetValue ждёт именно его, а не локализованное отображение, которое видит человек на экране.

### Поле → действие

| Тип поля | Действие | Нюанс |
| --- | --- | --- |
| text, email, password | SetValue | ставит value и возбуждает input с change |
| поле с маской и подсказками | Clear плюс SendKeys | процесс набора важнее скорости |
| select | SetValue по value опции | значение подсматривают в разметке; кастомный дропдаун — Click |
| checkbox, radio | Click по инпуту или label | состояние живёт в checked, а не в value |
| input типа file | SetUploadFiles | пути к файлам, не клики по диалогу |
| textarea | SetValue или SendKeys | перенос строк — символ в строке |

### Файловые инпуты: SetUploadFiles

Загрузка файла — поле, которое ломает интуицию сильнее остальных: клик открывает системный диалог, которым программа управлять не умеет, и на этом многие останавливаются. Останавливаться не нужно: диалог обходит сам браузер. chromedp.SetUploadFiles принимает селектор поля и список путей, отправляет браузеру команду dom.SetFileInputFiles, и файлы оказываются в поле так, будто их выбрал человек. Тот же путь внутри библиотеки срабатывает, если послать в поле SendKeys со строкой-путём: для input типа file клавиатурная механика отключается и печатание маршрутизируется в установку файлов, — но явное действие читается в коде лучше. Список путей важен: поле с атрибутом multiple принимает несколько файлов за раз, и они приходят одним вызовом. Два ограничения. Пути — это файловая система машины, где запущен Chrome: для локальной разработки это ваш компьютер, в Docker — контейнер, и отладка «файл не грузится» начинается с проверки, что путь существует именно там. И после установки файлов сайту положено событие, на котором он подхватит выбор; если фреймворк почему-то не среагировал, доталкивают Evaluate с dispatchEvent — та же механика событий, что и в обычных полях.

### Отчёт в поле загрузки — и проверка

```go
var files int
err := chromedp.Run(ctx,
        chromedp.WaitVisible("#doc"),
        chromedp.SetUploadFiles("#doc", []string{"/tmp/report.csv"}),
        chromedp.Evaluate(
                "document.querySelector('#doc').files.length",
                &files,
        ),
)
fmt.Println("файлов в поле:", files)
```

SetUploadFiles отправляет путь в dom.SetFileInputFiles для первого узла по селектору; приёмник Evaluate получает количество файлов, которые браузер реально положил в поле. Если путь не существует или поле не файловое, счётчик честно покажет ноль — обратное чтение превращает загрузку в проверяемую операцию, как Value для текстовых полей.

> **Живое место: Submit мимо валидации.** Классическая авария: на форме обязательные поля и JS-обработчик, который валидирует и шлёт данные XHR-ом. Программа вызывает chromedp.Submit — и форма «отправляется», но ничего не происходит: обработчик не запустился, пустые обязательные поля не пожаловались. Причина в механике: Submit вызывает метод form.submit() самой формы, а по правилам платформы он не возбуждает событие submit и пропускает HTML5-валидацию — форма уходит напрямую. Живой обработчик стоит на событии, которого не было. Спорное мнение с условием: Submit полезен, когда нужна именно сырая отправка без скриптов; во всех остальных случаях честнее Click по кнопке — тот же маршрут, что у пользователя, со всей валидацией и обработчиками.

### Enter, Submit и кнопка: три способа отправки

Отправить форму можно тремя путями, и между ними реальная разница, а не вкусовщина. Click по кнопке type=submit — самый честный: браузер возбуждает событие submit, запускает JS-обработчики, прогоняет HTML5-валидацию с подсказками у невалидных полей, и только потом уезжает запрос или переход. Enter в поле — SendKeys со строкой \r, у клавиатурного пакета для неё есть константа kb.Enter: механика та же, что у нажатия кнопки, если форма считает Enter отправкой, но на многостраничных формах Enter иногда нажимает другую кнопку — проверяйте на своём сайте. Submit — сырой метод form.submit(): в обход событий и валидации, как разобрано в живом месте выше. После любого способа начинается новый круг ожиданий, знакомый по пятому уроку: переход перезагружает страницу, XHR — нет, и в обоих случаях дожидаются узла, который существует только в новом состоянии. В цикле по однотипным страницам держите один способ отправки на весь обход: на странице бывает несколько кнопок с type=submit — для вкладок, фильтров, отзывов, — и селектор по типу выберет первую попавшуюся; привязывайте клик селектором контейнера конкретной формы, а не общим типом кнопки. Ошибки валидации — тоже узлы: блок с сообщением у поля, красная рамка, счётчик :invalid. Их читают теми же Text и Evaluate, и именно это отличает устойчивый сценарий от надёжного: надёжный после отправки не просто ждёт success, а умеет увидеть ошибку и принести её в лог.

> **Ошибки формы — данные, а не шум.** Прежде чем искать причину в коде парсера, прочитайте форму: chromedp.Text по селектору сообщения или Evaluate с document.querySelectorAll(':invalid').length покажет, что сайт отверг ввод и по какой причине. Одна строка чтения ошибки экономит час сравнения значений по полям. Тот же приём закрывает капчи-невидимки и пороги: сайт молча не сабмитит, но честно пишет причину в DOM.

### Автозаполнение go-программой: цикл по формам

Автозаполнение go-программой в промышленном виде — это цикл: строки данных на входе, формы на сайте, отчёт об ошибках на выходе. Скелет простой: на каждую строку — свежее ожидание формы, SetValue по полям, Click по кнопке, предикат на результат. Три детали отделяют работающий цикл от падающего. Первая: поля очищайте сами — SetValue перезаписывает, SendKeys допечатывает, и на второй итерации склейка гарантирует мусор. Вторая: падение одной формы не должно ронять обход — ошибка логируется с идентификатором строки, цикл идёт дальше, а сводка собирается в конце; ретраи и устойчивость здесь — территория пятнадцатого урока. Третья: если полей десятки, SetValue на каждое — это десятки обменов на форму; ускорение — один Evaluate с выражением, которое раскладывает значения по полям и дёргает события, — механика десятого урока. Отдельная честная оговорка: в старых статьях встречается действие SetSubmissionValues, будто бы заполняющее форму из карты одним вызовом — в текущей библиотеке его нет, массовое заполнение собирается циклом SetValue или JS-выражением. Готовые каталоги без JS-форм — территория Colly: [смежный курс](/courses/colly/) отправляет POST напрямую, когда браузер избыточен.

### Порядок работы с формой

- WaitVisible по селектору формы или контейнера полей
- текстовые поля — SetValue; маски и подсказки — Clear плюс SendKeys
- селект — SetValue по value опции; чекбоксы и радио — Click
- файлы — SetUploadFiles списком путей, затем проверка files.length
- отправка — Click по кнопке; Submit только для сырой отправки без обработчиков
- после отправки — WaitVisible на узел нового состояния и чтение ошибок валидации
- в цикле — ошибка формы логируется с идентификатором строки, обход продолжается

### Проверка: Submit и required

**Вопрос:** На форме обязательное поле пустое, программа вызывает chromedp.Submit. Что произойдёт?

- ✅ Форма отправится: form.submit не возбуждает событие и пропускает валидацию
- Ничего: браузер покажет подсказку у пустого поля
- Submit вернёт ошибку невалидной формы
- Сработает JS-обработчик, который отменит отправку

Submit вызывает метод form.submit(): по правилам платформы он не возбуждает событие submit и пропускает HTML5-валидацию, поэтому пустое обязательное поле не помешает отправке. Подсказку и отмену от обработчика даёт только честный маршрут — Click по кнопке отправки.

### Проверка: чем заполнять селект

**Вопрос:** У селекта есть опция с value="msk" и текстом «Москва». Как её выбрать?

- ✅ chromedp.SetValue("#city", "msk") — value опции, а не её текст
- chromedp.SetValue("#city", "Москва") — по видимому тексту
- Только Click по селекту, SetValue на селекте не работает
- chromedp.Submit по селекту

SetValue ставит свойство value селекта, поэтому нужен value опции — msk, а не видимый текст. Если совпадения нет, выбор остаётся пустым, и для кастомных дропдаунов из div-ов путь — клики. Submit здесь ни при чём: он отправляет родительскую форму, а не выбирает опцию.

### Что увидит сайт после SetValue на чекбоксе

```go
// <input type="checkbox" id="agree">
// err := chromedp.Run(ctx,
//   chromedp.SetValue("#agree", "on"),
// )
// после этого сайт читает checked чекбокса
```

**Что выведет программа?**

- ✅ checked остался false: SetValue меняет value, а не состояние
- checked стал true: значение on включило галочку
- checked стал true, но события не ушли
- Ошибка: SetValue не работает на чекбоксах

Механика SetValue — присваивание свойства value и события input с change. У чекбокса value — строка, которая уедет на сервер, а состояние живёт в checked, которое SetValue не трогает. Сайт получит события с невыставленной галочкой. Переключают чекбокс кликом.

### Соберите загрузку отчёта

Восстановите действия: значение поля, файл и отправка кнопкой.

```go
err := chromedp.Run(ctx,
        chromedp.WaitVisible("#upload-form"),
        chromedp.___("#title", "Отчёт за март"),
        chromedp.___("#doc", []string{"/tmp/report.csv"}),
        chromedp.___("button[type=submit]"),
        chromedp.WaitVisible("#done"),
)
```

Подсказка: Текст кладёт SetValue, файл — SetUploadFiles списком путей, честную отправку с валидацией — Click по кнопке.

Правильные ответы в пропусках: `SetValue`, `SetUploadFiles`, `Click`

### Расставьте сценарий загрузки файла

Соберите по порядку: контекст, ожидание формы, поле, файл, проверка и отправка.

Правильный порядок строк:

1. `ctx, cancel := chromedp.NewContext(context.Background())`
2. `defer cancel()`
3. `var files int`
4. `err := chromedp.Run(ctx,`
5. `  chromedp.WaitVisible("#upload-form"),`
6. `  chromedp.SetValue("#title", "Отчёт за март"),`
7. `  chromedp.SetUploadFiles("#doc", []string{"/tmp/report.csv"}),`
8. `  chromedp.Evaluate("document.querySelector('#doc').files.length", &files),`
9. `)`
10. `if err != nil {`
11. `  panic(err)`
12. `}`

### Карточки: формы от полей до отправки

- **chromedp.SetValue на select** — Ставит value селекта и выбирает опцию с совпавшим значением, события input и change уходят. Значение — value опции из разметки, не её текст.
- **Чекбокс и SetValue** — Галочку не ставит: SetValue меняет value — строку для сервера, а состояние живёт в checked. Чекбоксы и радио переключают Click по инпуту или label.
- **chromedp.SetUploadFiles** — Список путей в dom.SetFileInputFiles для первого узла селектора. Пути — файловая система машины, где запущен Chrome; несколько файлов одним вызовом для multiple.
- **chromedp.Submit** — Вызывает form.submit() родительской формы: событие submit не возбуждается, HTML5-валидация пропускается. Обработчики срабатывают только от Click по кнопке.
- **Enter в поле** — SendKeys со строкой \r (константа kb.Enter). Механика как у нажатия кнопки, если форма отправляется по Enter; проверяйте, какую кнопку выбирает форма.
- **Ошибки валидации** — Узлы DOM: сообщение у поля, счётчик :invalid через Evaluate. Читаются Text и Evaluate — чтение ошибки после отправки превращает сценарий в диагностируемый.

Что дальше: форма редко бывает первой страницей обхода — обычно за логином нужна сессия. Тринадцатый урок заберёт её целиком: [заголовки, куки и сессии](/courses/chromedp/lessons/13-zagolovki-kuki/) — как не логиниться на каждом шаге и чем cookies отличаются от заголовков авторизации. Если же форма стоит на странице с подгружаемыми списками, девятый урок про [ожидания](/courses/chromedp/lessons/09-ozhidaniya-elementov/) закроет гонки между заполнением и рендером. Практика — локально: понадобится установленный Go и Chrome, песочница сайта исполняет тематическую программу на чистом Go без браузера. Домашняя проверка на честность: возьмите форму с обязательными полями, отправьте её Submit с пустыми полями и посмотрите, уехала ли она, — ответ на этот вопрос дороже любого примера из урока.

## Коротко: что запомнить

- Форма собирается из четырёх действий: SetValue для текста, SendKeys для набора, Click для переключателей, SetUploadFiles для файлов.
- SetValue на select выбирает опцию по совпавшему value; текст опции и её value — разные строки.
- Чекбоксы и радиокнопки переключаются Click: их состояние в checked, а SetValue трогает только value.
- SetUploadFiles кладёт список путей в поле через dom.SetFileInputFiles; проверка — files.length через Evaluate.
- Submit вызывает form.submit(): событие submit не срабатывает, HTML5-валидация пропускается.
- Click по кнопке — честный маршрут отправки с обработчиками и валидацией; Enter — SendKeys со строкой \r.
- Ошибки валидации — узлы DOM: читайте их, прежде чем искать причину в парсере.
- В цикле автозаполнения поля чистят сами, падение формы логируется, а обход продолжается.

## Домашнее задание

Возьмите сайт с формой из трёх-пяти полей, обязательным полем и загрузкой файла, и соберите сценарий: ожидание формы, заполнение по типам полей из таблицы, загрузка файла с проверкой files.length, отправка кнопкой и чтение результата. Затем продублируйте отправку через Submit на форме с пустыми обязательными полями и сравните поведение с Click. Финал — цикл на три строки данных с заполнением одной и той же формы и логом ошибок по каждой строке; в лог добавьте время заполнения формы, чтобы видеть цену SetValue против Clear плюс SendKeys на своих полях.

## Вопросы и ответы по уроку

### SetValue сработал, но сайт поле не увидел. Что проверить первым?

Обратное чтение через Value: если в поле лежит ваше значение, проблема в событиях — сайт слушает что-то ещё. SetValue возбуждает input и change, но не события клавиатуры; маски и посимвольная валидация требуют Clear плюс SendKeys. Если же в поле пусто, проверьте селектор: у страниц с вкладками часто два элемента с одинаковым id в разных скрытых блоках. Отдельный случай — дата и число: value хранится в служебном формате, и «01.03.2025» сайту не подходит, хотя экран показывает именно его.

### Файл не грузится, ошибок нет. Где искать?

Проверьте три вещи: существует ли путь на машине, где запущен Chrome, — в Docker это файловая система контейнера; то ли это поле — селектор должен указывать на input типа file; и что сайт принял выбор — files.length через Evaluate покажет, сколько файлов браузер реально положил в поле. Если файлы в поле есть, а сайт не реагирует, добавьте событие change через Evaluate.

### Есть ли в chromedp действие, заполняющее форму из карты целиком?

Нет: в текущей библиотеке массовой установки значений формы одним вызовом нет — если в старых статьях встречается имя вроде SetSubmissionValues, в актуальном API его не ищите. Рабочие пути: цикл SetValue по полям или один Evaluate с выражением, которое раскладывает значения и возбуждает события, — на формах с десятками полей это заметно быстрее.
