Search code examples
c#webbrowser-controlcefsharp

CEFSHARP - ChromiumWebBrowser on get table row cell values


I solved most of my problems, but I couldn't find a solution for one of them. Previously, I was using Windows WebBrowser and getting a table result on a query screen in a dealer panel. Like this;

foreach (HtmlElement htmlobj in webBrowser1.Document.GetElementsByTagName("Table"))
 {
     if (htmlobj.GetAttribute("className") == "table table-striped")
     {
          foreach (HtmlElement tr in htmlobj.GetElementsByTagName("tbody"))
          {
               foreach (HtmlElement td in tr.Children)
              {
                    string s0 =  td.Children[0].InnerText;
                    string s1 =  td.Children[1].InnerText;
               }
          }
     }
}

How can I do this with ChromiumWebBrowser?

Thanks a lot for helps... ^_^


Solution

  • This can be achieved in CefSharp using EvaluateScriptAsync, by executing JavaScript to find the table's td elements and return them as an array, which C# will receive as a List<object>

    If you didn't already know, you have to usually wait until the page's MainFrame has loaded before executing any JavaScript, which you could implement like:

    //...
    ChromiumWebBrowser browser = new ChromiumWebBrowser("https://example.com"); // <- Your URL there
    
    browser.FrameLoadEnd += (sender, args) =>
    {
      // Wait for the MainFrame to finish loading
      if(args.Frame.IsMain)
          GetTable(); // method to call that executes JavaScript, etc
    }
    

    More information about when you can start executing JavaScript.

    Now, this is the code I made for EvaluateScriptAsync to return the td's innerText into C#:

    // assuming "browser" is the ChromiumWebBrowser and you're ready to start executing JavaScript (see above code)
    private void GetTable ()
    {
        const string script = @"(function(){
            let table = document.querySelector('table.table.table-striped'); // <table class='table table-striped'>
            let td = table.getElementsByTagName('td');
            return [ td[0].innerText, td[1].innerText ];
        })();";
    
        browser.GetMainFrame().EvaluateScriptAsync(script).ContinueWith(x =>
        {
            var response = x.Result;
    
            if (response.Success && response.Result != null)
            {
                // We cast values as CefSharp wouldn't know what to expect
                List<object> jsResult = (List<object>)response.Result;
    
                string s1 = (string)jsResult[0]; // td[0].innerText
                string s2 = (string)jsResult[1]; // td[1].innerText
    
                Console.WriteLine("s1: " + s1);
                Console.WriteLine("s2: " + s2);
                // In my example HTML page, it will output:
                // s1: This is 1st
                // s2: This is 2nd
            }
        });
    }
    

    I made this HTML example to test it on, as you didn't provide any:

    <table class="table table-striped">
        <tr>
            <th>One</th>
            <th>Two</th>
        </tr>
        <tr>
            <td>This is 1st</td>
            <td>This is 2nd</td>
        </tr>
    </table>