Как нажать на кнопку в окне webBrowser?
Очень часто в комментариях спрашивают: как нажать на кнопку в окне webBrowser? Так как этот вопрос очень часто повторяется, решил написать небольшую статью, в которой покажу несколько простых примеров, которые помогут решить данную задачу.
И так для начала создадим Windows Forms приложение, после чего поместим на форму: кнопку и элемент управления webBrowser (wb).
Затем создадим страницу index.html, с которой будем работать на протяжении всей этой статьи.
На этом подготовительная часть закончена, переходим к примерам.
Примеры
Чтобы выполнить код, приведенный в любом из ниже приведенных примеров, необходимо выполнить следующие действия:
1. Получить содержимое страницы, например это можно сделать с помощью метода Navigate или свойства URL.
private void button1_Click(object sender, EventArgs e) { wb.Navigate(URL); }
2. Дождаться полной загрузки страницы, используя событие DocumentCompleted.
private void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { //вставить код из примера }
3. Для того чтобы нажать на кнопку на странице, которая находится в окне элемента управления webbrower, необходимо воспользоваться методом InvokeMember, в который в качестве аргумента необходимо передать значение Click.
InvokeMember("Click");
Как нажать на кнопку с атрибутом id?
В первом примере научимся нажимать на кнопку, которая имеет атрибут id.
wb.Document.GetElementById("1").InvokeMember("Click");
Сначала с помощью метода GetElementById находим нужный нам элемент, в данном случае кнопку с указанным атрибутом id, после чего нажимаем на него.
Как нажать на кнопку с атрибутом name?
Во втором примере в качестве задачи нам нужно программно нажать на кнопку под номером шесть, которая имеет атрибут name. Как видно на картинке данный атрибут применяется сразу к двум html элементам, поэтому выполним несколько дополнительных действий: сначала найдем все кнопки на странице, а затем проверим у каждой из них наличие атрибута name и интересующего нас имени.
HtmlElementCollection elmCol; elmCol = wb.Document.Body.GetElementsByTagName("button"); foreach (HtmlElement elm in elmCol) { if (elm.GetAttribute("name") == "btnSix") { elm.InvokeMember("Click"); } }
результат
Как нажать на кнопку с атрибутом class?
В этом примере в качестве задачи нам необходимо нажать на третью кнопку, которая содержит атрибут class. О том, как найти html элемент по его классу я рассказывал в одной из предыдущих статей, поэтому сразу же перейдем к решению задачи.
HtmlElementCollection elmCol; elmCol = wb.Document.GetElementsByTagName("button"); foreach (HtmlElement elmBtn in elmCol) { if (elmBtn.GetAttribute("className") == "btnClick") { elmBtn.InvokeMember("Click"); } }
Если сейчас выполнить данный код, то в результате по очереди будут нажаты все кнопки, которые имеют атрибут class со значением btnClick. «Проблема» заключается в том, что данный атрибут можно применить сразу к нескольким элементам на странице, поэтому необходимо уточнить выборку, например, указав индекс интересующего нас элемента.
HtmlElementCollection elmCol; elmCol = wb.Document.GetElementsByTagName("button"); int i = 0; foreach (HtmlElement elmBtn in elmCol) { if (elmBtn.GetAttribute("className") == "btnClick" & i == 2) { elmBtn.InvokeMember("Click"); } ++i; }
результат
Как нажать на кнопку, которая находится в окне фрейма?
И последний пример, в котором рассмотрим ситуацию, когда нужно нажать на кнопку, которая находится внутри фрейма. И так для начала создадим ещё один html файл (frm.html), который содержит обычную форму с кнопкой.
Изменим содержимое страницы index.html
При работе с фреймами необходимо использовать проверку, которая позволяет дождаться полной загрузки страницы. Если ей не воспользоваться, то кнопка, в данном примере, будет нажата дважды, так как сначала будет загружена страница frm.html, после чего будет выполнен метод InvokeMember, а затем произойдет загрузка основной страницы index.html, после чего снова происходит нажатие на кнопку. В этом можно легко убедиться, если проследить за изменением значения (e.Url.AbsolutePath).
if (e.Url.AbsolutePath != wb.Url.AbsolutePath) { HtmlWindowCollection frames = wb.Document.Window.Frames; foreach (HtmlWindow frame in frames) { frame.Document.GetElementById("100").InvokeMember("Click"); } }
результат
Ещё один пример, в котором показано, как можно нажать на кнопку, которая находится в ячейке таблицы.
Дано:
<table class="myTable" border="1"> <tr><td><button onclick="">Купить</button></td></tr> <tr><td><button>Продать</button></td></tr> </table>
Решение:
HtmlElement body = webBrowser1.Document.Body; //получаем все элементы table HtmlElementCollection tables = body.GetElementsByTagName("table"); foreach (HtmlElement table in tables) { //находим таблицу с классом "myTable" if (table.GetAttribute("classname").Equals("myTable")) { //получаем все элементы button в таблице var buttons = table.GetElementsByTagName("button"); if (buttons.Count > 0) buttons[1].InvokeMember("Click"); } }
Либо можно найти кнопку «Продать» по значению, например:
//было if (buttons.Count > 0) buttons[1].InvokeMember("Click"); //стало foreach (HtmlElement button in buttons) { if (button.InnerText.Equals("Продать")) button.InvokeMember("Click"); }
Обратиться к нужной таблице можно не только с помощью цикла, но и по индексу, например:
//получаем первую таблицу HtmlElement table = webBrowser1.Document.GetElementsByTagName("table")[0]; //нажимаем вторую кнопку table.GetElementsByTagName("button")[1].InvokeMember("Click");
На этом всё, если вопросы, то оставляйте их в комментариях.
Читайте также:
Здравствуйте, почему то когда я в webbrowser нажимаю кнопку загрузить чего-нибудь фалй загружается но не отображается в закачанных после загрузки.
Вопрос о том, как пользоваться webbrowser Internet Explorer?
Просто я не понимаю, что за кнопка «загрузить чего-нибудь» и откуда появился список загруженных файлов…
Здравствуйте! Отличная статья. По Вашим примерам все понятно, все повторил и все сработало.
Но вот как применить к моей HTML странице не соображу(опыта 0,0).
Почитав азы HTML обнаружил, что кнопка расположена в ячейке таблицы и описывается так:
document.write(…);
…-это я заменил длинные имена.
Подскажите пожалуйста.
Спасибо.
В конце статьи (перед видео) добавил пример.
Спасибо за информацию. Очень помогла. Примеры HTML кода очень простые, а в реальных страницах гораздо все навороченнее. Как устроена моя страница я смог понять только в инспекторе FireFox. Оказалось моя кнопка вложена в 17 тэгов.
Хотелось бы спросить: 1.В инспекторе после открытия тэга таблицы идет тэг tbody, а при просмотре HTML кода такого тэга нет. Нужно ли выгружать колекцию элементов этого тэга и парсить их? 2. Как вывести (например в textbox) содержимое колекции (AttributeName, Value)
Спасибо.
В инспекторе после открытия тэга таблицы идет тэг tbody, а при просмотре HTML кода такого тэга нет.
tbody — это обычный html тэг, поэтому он должен отображаться как в инспекторе, так и в исходнике HTML кода страницы.
Нужно ли выгружать колекцию элементов этого тэга и парсить их?
Зависит от задачи.
Как вывести (например в textbox) содержимое колекции (AttributeName, Value)
AttributeName, Value — это свойства объекта. А о какой коллекции идёт речь?
К примеру я получаю коллекцию(HtmlElementCollection) таблиц в тэге боди методом:
боди.GetElementsByTagName(«таблички»). Переберая (foreach) элементы(HtmlElement) хотелось бы вывести в textbox какую нить информацию об элементе, его атрибутах и их значениях. Я могу пока только count-ом вывести количество элементов в коллекции.
Спасибо.
Получить все атрибуты элемента можно только, работая с DOM моделью html документа, а это уже неуправляемый код (в проект нужно добавить библиотеку mshtml).
Не стандартная кнопка, как с ней быть? Очень нужна помощь. Есть такой фрагмент страницы (таких кнопок на странице несколько, и какую кнопку пользователь нажал сервер определяет по значению скрытого поля)
Мне кроме того что нажать на кнопку нежно еще и выполнить присвоение переменной cp_f_ = 1 которая в скрытом поле. Т.е. еще раз пользователь на сайте нажимает одну из кнопок, выполняется скрипт ScriptName(), и при выполнении скрипта на сервере, сервер по значению переменной cp_f_ понимает что нужно сделать, как быть?