Webbrowser completed doesn't show all elements

久未见 提交于 2020-03-24 10:21:21

问题


I have a webbrowser which is loading a website. If the website firing the "completed" event, my HTMLElementCollection shows me a count of "179". If I click on the button and call the same method to get all HTMLElements, it tells me a count of "194". The problem is: if the "completed"-Event is firing, some HTMLElements are not loaded, and needs a longer time, and my HTMLElement which I need to click on it, is missing too.

To explain with code:

private void Webbrowser_DocumentComplete(object pDisp, ref object URL)
        {
                if (URL.ToString() == "testsite")
                {
                    HtmlElementCollection c1 = webBrowser1.Document.GetElementsByTagName("div");
                    foreach (HtmlElement e2 in c1)
                    {
                        if (e2.GetAttribute("classname") == "btn3")
                        {
                            if (e2.InnerText == "follow")
                            {
                                e2.InvokeMember("click");
                            }
                        }
                    }
                }
        }

The count of "c1" is 179.

If I wait 1-2 seconds and click then on a button with the same code like:

private void Button1_Click(object sender, EventArgs e)
        {
HtmlElementCollection c1 = webBrowser1.Document.GetElementsByTagName("div");
                    foreach (HtmlElement e2 in c1)
                    {
                        if (e2.GetAttribute("classname") == "btn3")
                        {
                            if (e2.InnerText == "follow")
                            {
                                e2.InvokeMember("click");
                            }
                        }
                    }
        }

The count of "c1" is 194.

The question is: how can I wait some seconds if the page is build completed? I need the count of 194 because there is ONE HTMLElement which I want to click on it!


回答1:


You can handle this by using a Timer. The following function is done to wait for some seconds.

    public void WaitForSecond(int min)
    {
        System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
        if (min == 0 || min < 0) return;
        timer1.Interval = min * 1000;
        timer1.Enabled = true;
        timer1.Start();
        timer1.Tick += (s, e) =>
        {
            timer1.Enabled = false;
            timer1.Stop();

        };
        while (timer1.Enabled)
        {
            Application.DoEvents();
        }
    }

Also, you can reduce your code by LINQ

HtmlElement e2= (from HtmlElement element in 
                  webBrowser1.Document.GetElementsByTagName("div") 
                  select element)
                  .Where(x => x.GetAttribute("classname") != null 
                           && x.GetAttribute("classname") =="btn3"
                           && x.InnerText != null 
                           && x.InnerText == "follow").FirstOrDefault();

First, check your HTML element is loaded or not otherwise wait. If the HTML element is loaded then process the further steps

HtmlElement e2= null;
int cnt = 0;
            do
            {
                WaitForSecond(1);
                cnt++;

                if (cnt > 60)
                {
                   MessageBox.Show("Web page not loaded");
                    break;
                }
                e2= (from HtmlElement element in webBrowser1.Document.GetElementsByTagName("div") select element)
                .Where(x => x.GetAttribute("classname") != null 
                       && x.GetAttribute("classname") =="btn3"
                       && x.InnerText != null 
                       && x.InnerText == "follow").FirstOrDefault();    
            } while e2 == null);



回答2:


Thank you to all of you, but I google'd again and found a very good (for me working) workaround. For all: I want that after navigating to a page, a timer (or something else) wait for x-seconds and during the timer is waiting, the page is loading, and after that, I want to click on the button.

First of all: the code isn't done by me. It's from https://dotnet-snippets.de/snippet/webbrowser-navigate-and-wait-seconds/15171

First declare this at the beginning:

  public delegate void NavigateDoneEvent();
        public static event NavigateDoneEvent Done;

        private static System.Windows.Forms.Timer wait;

You don't need to use this as static.

After that you need to create this function

 public static void Wait(WebBrowser Browser, string Url, double Seconds)
        {
            Browser.Navigate(Url);

            wait = new System.Windows.Forms.Timer();
            wait.Interval = Convert.ToInt32(Seconds * 1000);

            wait.Tick += (s, args) =>
            {
                if (Done != null) Done();
                wait.Enabled = false;
            };

            wait.Enabled = true;
        }

And you can call this function like:

Wait(webBrowser1, "somesite.com", 20);
            Done += afterWaitDoSomething;


来源:https://stackoverflow.com/questions/55939504/webbrowser-completed-doesnt-show-all-elements

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!