Добрый день.
Разберем такой случай когда нам присылают ссылку на подтверждение, а после перехода по ссылке открывается страница с кнопкой подтверждения на которую надо нажать. Либо просто надо нажать на кнопку на странице HTML. Если с переходом по ссылке более менее все понятно, то с нажатием кнопки довольно не просто. Давайте разбираться.
Немного теории.
Обычно копка является частью HTML формы. Соответственно нажимая на кнопку браузер формирует ответ серверу, обычно в POST запросе, собирая все данные с input элементов в веб-формы. Проще говоря цель нажатия кнопки это отослать представлениt заполненной веб-формы на веб-сервер.
Возьмем следующий пример:
<form method="POST" name="login" action="Home/Result"> <input type="hidden" name="id" value="id"> <input type="hidden" name="sitename" value="deptech"> <input type="submit" name="send" class="submit"> </form>
В этом примере имеется форма с именем «login» методом «POST» и обработчиком «Home/Result». И имеются поля id и sitename которые уже заполнены значениями id и deptech соответственно, также имеется кнопка с именем «send».
В итоге нужно сформировать представление веб формы отослать на обработчик «Home/Result».
По умолчанию интернет-тип данных для отправки вэб-форм медиа это: «application/x-www-form-urlencoded».
Это формат для кодирования пар ключ-значение с возможностью дублирования ключей. Каждая пара ключ-значение отделяется символом &, ключ отделён от значения символом = . В ключах и значениях пробелы заменяются на знак +, и затем, используя URL-кодирование, заменяются все не буквенно-цифровые символы.
Для нашего примера :
Id: id
sitename: deptech
Будет закодирована следующим образом
Id=id&sitename=deptech
WebClient нам в помощь.
Так как мы работаем на прямую с протоколом то этот ответ мы должны сформировать самостоятельно.
Открываем проект в VisualStudio, создаем проект под названием, например, ClickHtmlButton. Кидаем на форму три текстбокса и кнопку.
В первый текстбокс будем подставлять нашу ссылку, во второй будем обозначим как имя нашей html кнопки. Ну и третье поле будем записывать ответ сервера после нажатия htmlкнопки.
В обработчик кнопки добавим следующий код:
private void button1_Click(object sender, EventArgs e) { string htmlLink = textBox1.Text; string htmlButtonName = textBox2.Text; ButtonClicker buttonClicker = new ButtonClicker(); string responseHtml = buttonClicker.ButtonClick(htmlLink, htmlButtonName); textBox3.Text = responseHtml; }
Установка HTMLAgilityPack
Для решения проблемы нам понадобиться также дополнение HTML Agility Pack это HTML парсер. Его можно найти в Nuget через поиск либо добавить через ту же консоль nuget командой:
Install-Package HtmlAgilityPack.
Потом в класс добавим
using hap= HtmlAgilityPack;
Добавим два класса которые будут описывать нашу форму и поля ввода
public class Inputitem { /// <summary> /// Тип элемента формы /// </summary> public string InputType { get; set; } /// <summary> /// Имя элемента формы /// </summary> public string InputName { get; set; } /// <summary> /// Значение элемента формы /// </summary> public string InputValue { get; set; } /// <summary> /// Форма в которой содержатся элементы /// </summary> public HtmlFormValue FormAtribute { get; set; } }
Класс который будет описывать нашу форму
public class HtmlFormValue { public HtmlFormValue() { ListInputs = new List<Inputitem>(); } /// <summary> /// Имя вебформы, может отсутствовать /// </summary> public string NameForm { get; set; } /// <summary> /// Oбработчик, к которому обращаются данные формы при их отправке на сервер /// </summary> public string ActionForm { get; set; } /// <summary> /// Метод который использует форма для отправки на сервер Post или Get /// </summary> public string MethodForm { get; set; } /// <summary> /// Список всех всех input Html элементов в вебформе /// </summary> public List<Inputitem> ListInputs { get; set; } /// <summary> /// Список элементов в формате 'Имя=Значение' /// </summary> /// <returns></returns> public List<string> GetInputsNameValue()=>ListInputs .Select(x=>$"{x.InputName}={x.InputValue}") .ToList(); }
Добавим недостающий класс ButtonClicker в проект.
using System.Net; using System; using hap = HtmlAgilityPack; using System.Collections.Generic; using System.Linq; namespace ClickHtmlButton { public class ButtonClicker { public string ButtonClick(string URI, string ButtonValue) { Uri uri = new Uri(URI); using (WebClient wc = new WebClient()) { //Загружаем страницу HTML в string string HtmlString = wc.DownloadString(uri); //Создаем HtmlAgilityPack hap.HtmlDocument HtmlDoc = new hap.HtmlDocument(); //Загружаем Html документ из строки HtmlDoc.LoadHtml(HtmlString); //Выбираем все формы на странице hap.HtmlNodeCollection formNodes = HtmlDoc.DocumentNode.SelectNodes("//form"); List<HtmlFormValue> HtmlForms = new List<HtmlFormValue>(); var AllInputs = new List<Inputitem>(); if (formNodes != null) { foreach (var formAtribute in formNodes) { HtmlFormValue FormAtribute = new HtmlFormValue { ActionForm = formAtribute.Attributes["action"].Value, MethodForm = formAtribute.Attributes["method"].Value, NameForm = formAtribute.Attributes["name"].Value }; //Выбираем все imputs на форме hap.HtmlNodeCollection inputsNodes = formAtribute?.SelectNodes("//input"); if (inputsNodes != null) { AllInputs = inputsNodes .Select(x => new Inputitem { InputName = x.Attributes["name"]?.Value ?? "", InputType = x.Attributes["type"].Value, InputValue = x.Attributes["value"]?.Value ?? "", FormAtribute = FormAtribute } ).ToList(); } FormAtribute.ListInputs = AllInputs; HtmlForms.Add(FormAtribute); } HtmlFormValue FindForm = AllInputs.First(x => x.InputName == ButtonValue).FormAtribute; if (FindForm != null) { //Собираем запрос //Указываем способ кодировки wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded"; //добавляем параметры string myParameters = string.Join("&", FindForm.GetInputsNameValue()); //Формируем строку на указанный ресурс string uripath = $"{uri.AbsoluteUri}{FindForm.ActionForm}"; //отправляем и получаем результат string HtmlResult = wc.UploadString(uripath, myParameters); return HtmlResult; } else { return ""; } } else { return ""; } } } } }
Для тестов будем использовать нашу форму.
<form method="POST" name="login" action="Home/Result"> <input type="hidden" name="id" value="id"> <input type="hidden" name="sitename" value="deptech"> <input type="submit" name="send" class="submit"> </form>
Запускаем и тестим: