【问题标题】:Webbrowser completed doesn't show all elements浏览器完成不显示所有元素
【发布时间】:2019-05-03 01:14:26
【问题描述】:

我有一个正在加载网站的网络浏览器。如果网站触发“完成”事件,我的 HTMLElementCollection 会显示“179”的计数。如果我单击按钮并调用相同的方法来获取所有 HTMLElement,它会告诉我“194”的计数。问题是:如果“完成”事件正在触发,一些 HTMLElement 没有加载,需要更长的时间,而我需要点击它的 HTMLElement 也丢失了。

用代码解释:

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");
                            }
                        }
                    }
                }
        }

“c1”的计数是 179。

如果我等待 1-2 秒,然后单击具有相同代码的按钮,例如:

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");
                            }
                        }
                    }
        }

“c1”的计数是 194。

问题是:如果页面构建完成,我该如何等待几秒钟? 我需要 194 的计数,因为我想点击一个 HTMLElement!

【问题讨论】:

  • @Jimi 为什么这对我有帮助?
  • 你没有阅读那些笔记。具体来说,耦合DocumentCompleted 事件和WebBrowser.ReadyState。与 HTML 页面的内部文档相关的任何其他内容,可以包含多个 Document。对于 HTML 页面中的每个文档,都会引发一个 DocumentCompleted 事件。不同的文档是异步加载的。
  • 但我只想实现我可以等待 5 秒,页面正在加载,因为控件需要时间,5 秒后我尝试点击,比如 while (DateTime.Now 但网络浏览器停止加载
  • 您需要等到您要查找的 HtmlElement 被加载并呈现。没有特定的 timeout 等待。当它准备好时,它就准备好了,你会得到它。仔细阅读我链接的内容并查看相关代码。顺便说一句,这正是您需要做的事情。

标签: c# webbrowser-control


【解决方案1】:

您可以使用计时器来处理这个问题。下面的函数完成等待几秒。

    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();
        }
    }

另外,您可以通过 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();

首先,检查您的 HTML 元素是否已加载,否则请等待。如果加载了 HTML 元素,则处理进一步的步骤

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);

【讨论】:

  • 有点问题。在此操作期间网站未加载。它被冻结了,这就是我找不到这个元素的原因。
  • 然后你可以使用 WaitForSecond 函数增加等待时间。这样它就会等到您的网站页面加载。可以给网页链接吗?
  • 是的,这是可能的,我找到了解决方案(请参阅下面的答案)
【解决方案2】:

谢谢大家,但我再次谷歌搜索并找到了一个非常好的(对我来说工作)解决方法。 对于所有人:我希望在导航到页面后,计时器(或其他东西)等待 x 秒,在计时器等待期间,页面正在加载,之后,我想点击按钮。

首先:代码不是我做的。来自https://dotnet-snippets.de/snippet/webbrowser-navigate-and-wait-seconds/15171

首先在开头声明这个:

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

        private static System.Windows.Forms.Timer wait;

你不需要把它当作静态的。

之后你需要创建这个函数

 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;
        }

你可以像这样调用这个函数:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-14
    相关资源
    最近更新 更多