Search code examples
c#webbrowser-controlgeckogeckofx

gecko browser button click doesn't work c#


I'm tiring to emulate the google search with gecko web browser. so far i have able to go to the google page and then search some thing like this:

    geckoWebBrowser1.Navigate("https://www.google.com/");
    await Task.Run(() => CheckDocumentLoaded());

    var page = geckoWebBrowser1.Document.GetElementById("lst-ib");
    (page as GeckoHtmlElement).Focus();
    (page as GeckoInputElement).Value = "something";

now i simply want to click on the search button. so i added this to the first part:

    var button = new GeckoButtonElement(geckoWebBrowser1.Document.GetElementById("mKlEF").DomObject);
    button.Click();

but funny things happens. if i run this code after the first part nothing will happens. but if i created a button and put the code on it it works just fine.

private void Button1_Click(object sender, EventArgs e)
{
    var button = new GeckoButtonElement(geckoWebBrowser1.Document.GetElementById("mKlEF").DomObject);
    button.Click();

    return;
}

but i have to click on button manually in order to make it work. its really confusing. i have no idea what causes this!!

NOTE:

  1. you have to use this user agent if you want to the code works: (Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko)

  2. i don't want to use the SendKeys.Send("{ENTER}").

  3. if i press the button programmatically its not work either.


Solution

  • I played around and recreated your scenario in a WPF app.

    I got it working using the DocumentCompleted event that

    occurs after the browser has finished parsing a new page and updated the Document property.

    I subscribe to the event listener before navigation and remove it once the handler is invoked.

    Then, I call the first element of the form to submit the search.

    (_browser.Document.GetElementsByTagName("form").First() as GeckoFormElement).submit();
    

    Full code sample: WPF app

    using Gecko;
    using Gecko.DOM;
    using System.Windows;
    using System.Windows.Forms.Integration;
    using System.Linq;    
    namespace GeckoWpf {
        public partial class MainWindow : Window {
            public MainWindow() {
                InitializeComponent();
                Gecko.Xpcom.Initialize("Firefox");
            } 
    
            void browser_DocumentCompleted(object sender, System.EventArgs e) {
                 //unsubscribe
                _browser.DocumentCompleted -= browser_DocumentCompleted;
    
                XPathResult xpathResult = _browser.Document.EvaluateXPath("//div/input");
                var foundNodes = xpathResult.GetNodes();
                foreach (var node in foundNodes) {
                    GeckoInputElement txtbox = new GeckoInputElement(node.DomObject);
                    txtbox.Value = "Mona Lisa"; //add the search term
                }    
                (_browser.Document.GetElementsByTagName("form").First() as GeckoFormElement).submit();
            }
    
            WindowsFormsHost _host = new WindowsFormsHost();
            GeckoWebBrowser _browser = new GeckoWebBrowser();    
            private void Window_Loaded(object sender, RoutedEventArgs e) {
                _browser.DocumentCompleted += browser_DocumentCompleted;
                _host.Child = _browser;    GridWeb.Children.Add(_host);    
                _browser.Navigate("https://www.google.com/");
            }
        }
    }
    

    Note: This approach may not work on all pages since DocumentComplete may get fired multiple times for various reasons (e.g. i/frames, AJAX and other dynamic stuff).

    PS: Nonetheless, your endeavor may or may not be legal.
    You may want to consider using Google's custom search API or alternatives like SerpApi instead.