none
WebBrowser Программно нажать на вход после заполнения формы. RRS feed

  • Вопрос

  • void Enter(WebBrowser wb, string account, string password)
            {
                wb.Document.GetElementById("userid").SetAttribute("value", account);
                wb.Document.GetElementById("pass").InnerText = password;
           
                foreach (HtmlElement he in wb.Document.GetElementsByTagName("input"))
                {
                    if (he.GetAttribute("value").Equals("Einloggen"))
                    {
                        he.InvokeMember("click");
                    }
                }
            }

    Стандартный код. в режиме пошаговой отладки все хорошо, заполняю форму и авторизуюсь. Но когда программа в свободном полете, то выяснилось, что она постоянно прыгает на странице авторизации и не может войти. Могу предположить, что Логин и Пароль не успевают быть записаны, как программа нажимает кнопку авторизации. Какие идеи?


    Наблюдаю как брауйзер прыгает на одной странице, попытал счастье нажать кнопку мышью когда форма была заполнена и вполне смог войти, но надо сделать это программой  
    • Изменено Magals 15 мая 2013 г. 13:24

Ответы

  • А что значит попытка ввода и как вы определяете что она была?

    У меня нет аккаунта на ebay но при использовании случайных логина и пароля форма отправляется на сервер и появляется сообщение о том что пароль неверный.

    вот код который у меня работает

            private void button7_Click(object sender, EventArgs e)
            {
                wb.Navigate("https://signin.ebay.de/ws/eBayISAPI.dll?SignIn&ru=http%3A%2F%2Fwww.ebay.de%2F");
                while (wb.ReadyState != WebBrowserReadyState.Complete)
                {
                    Application.DoEvents();
                }
                Enter(wb, "12sdffsdf3fsdfsd", "sdfsdf12sdfsdf3sdfsdf");
            }
    
            void Enter(WebBrowser wb, string account, string password)
            {
                wb.Document.GetElementById("userid").SetAttribute("value", account);
                wb.Document.GetElementById("pass").InnerText = password;
    
                foreach (HtmlElement he in wb.Document.GetElementsByTagName("input"))
                {
                    if (he.GetAttribute("value").Equals("Einloggen"))
                    {
                        he.InvokeMember("click");
                    }
                }
            }

    • Помечено в качестве ответа Magals 15 мая 2013 г. 23:58

Все ответы

  • Вероятно есть решение для WebBrowser, но я делаю по другому. По факту при нажатии на кнопку выполняется некий скрипт который сводится к тому, что все данные из формы передаются POST-запросом на сервер. Вы можете имитировать такой запрос минуя заполнения формы и нажатие кнопки. Подробнее об этом рассказано тут.

    Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!

    Отвечающий
  • Предположу что в режиме отладки вы дожидаетесь загрузки страницы, а самостоятельно приложение или этого не делает или делает некорректно. Приведите код который выполняется между вызовом метода WebBrowser.Navigate() и методом Enter();

    ПС поробуйте в начало метода Enter вставить код

                while (wb.ReadyState != WebBrowserReadyState.Complete)
                {                
                    Application.DoEvents();
                }

     
    • Изменено Bazzzy 15 мая 2013 г. 14:24
    • Предложено в качестве ответа Taras KovalenkoBanned 15 мая 2013 г. 15:38
  • while (wb.ReadyState != WebBrowserReadyState.Complete)
                {                
                    Application.DoEvents();
                }
    не помог
    wb.Navigate("Сайт авторизации");
                    wb.DocumentCompleted += (s, ee) =>
                    {
                        if ("Проверяем если мы на сайте авторизации")
                        {
                            
                            Enter(wb, "акк", "пасс");
                            wb.Navigate("после авторизации двигаемся дальше  по сайту");
                        }


    • Изменено Magals 15 мая 2013 г. 15:32
  • Не изменяя метода Enter():

                wb.Navigate("Сайт авторизации");
                while (wb.ReadyState != WebBrowserReadyState.Complete)
                {
                    Application.DoEvents();
                }                   
                Enter(wb, "акк", "пасс");
                wb.Navigate("после авторизации двигаемся дальше  по сайту");
                
     

    или

    bool isDocumentCompleted = false; private void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { isDocumentCompleted = true; } private void button7_Click(object sender, EventArgs e) { wb.Navigate("Сайт авторизации");

    isDocumentCompleted = false; wb.DocumentCompleted+=new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted); while (!isDocumentCompleted) { Application.DoEvents(); } Enter(wb, "акк", "пасс"); wb.Navigate("после авторизации двигаемся дальше по сайту"); }

    Если честно, что из двух вариантов точнее определит полную загрузку страницы я не помню.


    • Изменено Bazzzy 15 мая 2013 г. 16:51
  • Не изменяя метода Enter():

                wb.Navigate("Сайт авторизации");
                while (wb.ReadyState != WebBrowserReadyState.Complete)
                {
                    Application.DoEvents();
                }                   
                Enter(wb, "акк", "пасс");
                wb.Navigate("после авторизации двигаемся дальше  по сайту");
                
     

    или

    bool isDocumentCompleted = false; private void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { isDocumentCompleted = true; } private void button7_Click(object sender, EventArgs e) { wb.Navigate("Сайт авторизации");

    isDocumentCompleted = false; wb.DocumentCompleted+=new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted); while (!isDocumentCompleted) { Application.DoEvents(); } Enter(wb, "акк", "пасс"); wb.Navigate("после авторизации двигаемся дальше по сайту"); }

    Если честно, что из двух вариантов точнее определит полную загрузку страницы я не помню.

    увы никакой вариант не помог. да и событие возникает только после окончания загрузки страницы, и в доп проверке не вижу смысла

  • По этой ссылке есть все что вам нужно :) Там есть как дождаться полностью загрузки страницы, как отловить ошибки http и много другого.

    А тут как провести авторизацию на сайте с помощью POST-запросов, все очень доступно показано, если что на видео он использует FireBug :)

    благодарен за видео, может когда ни будь воспользуюсь.

    увы мне не помогло. в авторизации на странице ebay.de используется определенная черная магия и без такого же колдовства не обойтись.

    если быть более подробно:

    MfcISAPICommand=SignInWelcome
    &bhid=a1%253D10%7Ea2%253D0%7Ea3%253D16540%7Ea4%253DMozilla%7Ea5%253DMicrosoft%2520Internet%2520Explorer%7Ea6%253D5.0%2520%28compatible%253B%2520MSIE%252010.0%253B%2520Windows%2520NT%25206.2%253B%2520WOW64%253B%2520Trident%252F6.0%253B%2520.NET4.0E%253B%2520.NET4.0C%253B%2520.NET%2520CLR%25203.5.30729%253B%2520.NET%2520CLR%25202.0.50727%253B%2520.NET%2520CLR%25203.0.30729%29%7Ea7%253D0%7Ea8%253Dru-RU%7Ea9%253Dtrue%7Ea10%253Dx86%7Ea11%253Dtrue%7Ea12%253DWin32%7Ea13%253Dru-RU%7Ea14%253DMozilla%252F5.0%2520%28compatible%253B%2520MSIE%252010.0%253B%2520Windows%2520NT%25206.2%253B%2520WOW64%253B%2520Trident%252F6.0%253B%2520.NET4.0E%253B%2520.NET4.0C%253B%2520.NET%2520CLR%25203.5.30729%253B%2520.NET%2520CLR%25202.0.50727%253B%2520.NET%2520CLR%25203.0.30729%29%7Ea15%253Dtrue%7Ea16%253Dru-RU%7Ea17%253Dwindows-1251%7Ea18%253Dsignin.ebay.de%7Ea19%253D86%7Ea20%253D86%7Ea21%253Dtrue%7Ea22%253D0%7Ea23%253D2133%7Ea24%253D1200%7Ea25%253D24%7Ea26%253D1156%7Ea27%253Dna%7Ea28%253DWed%2520May%252015%252011%253A04%253A53%2520PDT%25202013%7Ea29%253D-7%7Ea30%253Dabk%253D6%252C2%252C9200%252C16384%257Cdht%253D10%252C0%252C9200%252C16540%257Cieh%253D10%252C0%252C9200%252C16540%257Ciee%253D6%252C2%252C9200%252C16540%257Cwmp%253D12%252C0%252C9200%252C16420%257Cobp%253D10%252C0%252C9200%252C16540%257Coex%253D6%252C2%252C9200%252C16384%257C%7Ea31%253Dyes%7Ea32%253Dwow64%7Ea33%253Dyes%7Ea34%253Dno%7Ea35%253Dno%7Ea36%253Dyes%7Ea37%253Dno%7Ea38%253Donline%7Ea39%253Dno%7Ea40%253DWin32%7Ea41%253Dno%7Ea42%253Dno%7Ea43%253D
    &UsingSSL=1
    &inputversion=2
    &lse=true
    &lsv=WIN+11%2C7%2C700%2C169&mid=AQAAAT0Jf7nYAAUxM2QyYzU5NWJhNS5hNWViNjE4LmUzODAuZmZmODI5ZjVfc45l8V4zYNhO%2FeViRXiXoQC4OQ**
    &kgver=1
    &kgupg=1
    &kgstate=r
    &omid=
    &hmid=
    &rhr=f
    &siteid=77
    &co_partnerId=2
    &ru=
    &pp=
    &pa1=
    &pa2=
    &pa3=
    &i1=-1
    &pageType=-1
    &rtmData=
    &bUrlPrfx=5dccc713ea9on4ov
    &rqid=a95dccc713e0a5e545e7d827ffcd256b
    &kgct=AQAAAT6lfHnQAAVMZkxHdmwxaXIxSmMxSkMvcVVsYnBiY3M2VVo5VHJwTnoxazZXSEdBSVFBPXgwrCe815FVhuXG0%252FuFKH7rq9F0
    &userid=блабла
    &pass=блобло
    &keepMeSignInOption=1
    &sgnBt=Einloggen
    &htmid=sl%253DAQAAAT5x%25252FOHRAAUxM2U3NmQxNDZiYS5hNTY2ZTNlLjUzNTI1LmZmZjA4NTEw6bIIyMUfGS5U38p8Rze%25252Frld8w1o*%257Cslnew%253Dfalse%257Cht5%253DAQAAAT0Jf7nYAAUxM2QyYzU5NWJhNS5hNWViNjE4LmUzODAuZmZmODI5ZjVfc45l8V4zYNhO%25252FeViRXiXoQC4OQ**%257Cht5new%253Dfalse
    &kdata=%251E%251F%2511%251E1368641093875%251E1%251FV%251E1368641094078%251E1%251F%2511%251E1368641094195%251E0%251FV%251E1368641094203%251E0%251F

    так выглядит Post -запрос на авторизацию там. данные берутся с формы заполнения, которые попытался получить через парсинг HtmlAgilityPack. всё бы ничего, но последние две переменные (&htmid, &kdata) просто не откуда было взять. Смотрю код страницы через "средства разработчика" в IE10, нахожу htmid, а kdata-нет. окей, смотрю в html-код страницы, и не нахожу ни того ни другого

    как такое может быть?

    вообще проблему решил, если вообще это можно назвать решением, на столько отвратительным способом, что сам себе готов руки отрубить и...скушать.

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

    private void button10_Click(object sender, EventArgs e)
            {
                wb.Document.GetElementById("userid").SetAttribute("Value", acс);
                wb.Document.GetElementById("pass").SetAttribute("Value", pass);
                wb.Document.GetElementById("sgnBt").InvokeMember("click");
            }
    и вызываю событие клик.
                    wb.Navigate("сайт авторизации");
                    wb.DocumentCompleted += (s, ee) =>
                    {
                        if ("проверка на страницу авторизации")
                        {
                            button10_Click(null, null);
                            wb.Navigate( "катаемся дальше");

  • конечно, надо было следовать этому уроку, http://www.gotdotnet.ru/blogs/AleksejSergeevich/6559/ что и сделаю чуть по позже, но программу надо было написать быстро, и чтоб понимал происходящие действия
  • Закомментируйте весь лишний код так чтобы отрабатывал только метод Enter и только один раз. Отпишитест заполенены ли поля формы.  
  • Закомментируйте весь лишний код так чтобы отрабатывал только метод Enter и только один раз. Отпишитест заполенены ли поля формы.  

    Поля заполнялись и так и попытка ввода тоже была.

    сейчас сделал как вы сказали, всё так же(заполняется форма), но уже страница не скачет, ибо вводятся данные один раз

  • Что такое поытка ввода? На странице есть JS или фреймы? Попробуйте вызвать вместо

    foreach (HtmlElement he in wb.Document.GetElementsByTagName("input"))
                {
                    if (he.GetAttribute("value").Equals("Einloggen"))
                    {
                        he.InvokeMember("click");
                    }
                }

    вызвать

     wb.Document.GetElementsByTagName("form")[0].InvokeMember("submit");

     
  • Что такое поытка ввода? На странице есть JS или фреймы? Попробуйте вызвать вместо

    foreach (HtmlElement he in wb.Document.GetElementsByTagName("input"))
                {
                    if (he.GetAttribute("value").Equals("Einloggen"))
                    {
                        he.InvokeMember("click");
                    }
                }

    вызвать

     wb.Document.GetElementsByTagName("form")[0].InvokeMember("submit");

     

    тфу блин(попытка входа).

    программа снова не работает. походу у меня было самовнушение, или луна опять встала в фазу с Юпитером.

    ни каких js или фреймов на форме "https://signin.ebay.de/ws/eBayISAPI.dll?SignIn&ru=http%3A%2F%2Fwww.ebay.de%2F"

     wb.Document.GetElementsByTagName("form")[0].InvokeMember("submit");

    тоже самое
    самое интересно в пошаговой отладке,  захожу, а когда прога сама, то нет
    • Изменено Magals 15 мая 2013 г. 22:36
  • А что значит попытка ввода и как вы определяете что она была?

    У меня нет аккаунта на ebay но при использовании случайных логина и пароля форма отправляется на сервер и появляется сообщение о том что пароль неверный.

    вот код который у меня работает

            private void button7_Click(object sender, EventArgs e)
            {
                wb.Navigate("https://signin.ebay.de/ws/eBayISAPI.dll?SignIn&ru=http%3A%2F%2Fwww.ebay.de%2F");
                while (wb.ReadyState != WebBrowserReadyState.Complete)
                {
                    Application.DoEvents();
                }
                Enter(wb, "12sdffsdf3fsdfsd", "sdfsdf12sdfsdf3sdfsdf");
            }
    
            void Enter(WebBrowser wb, string account, string password)
            {
                wb.Document.GetElementById("userid").SetAttribute("value", account);
                wb.Document.GetElementById("pass").InnerText = password;
    
                foreach (HtmlElement he in wb.Document.GetElementsByTagName("input"))
                {
                    if (he.GetAttribute("value").Equals("Einloggen"))
                    {
                        he.InvokeMember("click");
                    }
                }
            }

    • Помечено в качестве ответа Magals 15 мая 2013 г. 23:58
  • А что значит попытка ввода и как вы определяете что она была?

    У меня нет аккаунта на ebay но при использовании случайных логина и пароля форма отправляется на сервер и появляется сообщение о том что пароль неверный.

    вот код который у меня работает

            private void button7_Click(object sender, EventArgs e)
            {
                wb.Navigate("https://signin.ebay.de/ws/eBayISAPI.dll?SignIn&ru=http%3A%2F%2Fwww.ebay.de%2F");
                while (wb.ReadyState != WebBrowserReadyState.Complete)
                {
                    Application.DoEvents();
                }
                Enter(wb, "12sdffsdf3fsdfsd", "sdfsdf12sdfsdf3sdfsdf");
            }
    
            void Enter(WebBrowser wb, string account, string password)
            {
                wb.Document.GetElementById("userid").SetAttribute("value", account);
                wb.Document.GetElementById("pass").InnerText = password;
    
                foreach (HtmlElement he in wb.Document.GetElementsByTagName("input"))
                {
                    if (he.GetAttribute("value").Equals("Einloggen"))
                    {
                        he.InvokeMember("click");
                    }
                }
            }


    вы мой волшебник. работает! благодарю за труд
    • Изменено Magals 15 мая 2013 г. 23:58
  • проблема та же появилась, но исправил уже

    wb.Navigate("сайт авторизации");
                    while (wb.ReadyState != WebBrowserReadyState.Complete)
                    {
                        Application.DoEvents();
                    }
                    Enter2(wb, "acc", "pass");
                    while (wb.ReadyState == WebBrowserReadyState.Complete)
                    {
                        Application.DoEvents();
                    }
                    wb.Navigate("идем дальше ");