【问题标题】:Waiting for WebBrowser to fully load between multiple Navigate() calls等待 WebBrowser 在多个 Navigate() 调用之间完全加载
【发布时间】:2012-05-01 13:56:29
【问题描述】:

我正在冒险进入 WPF - 第一次在 (VB).NET 中 - 并尝试重新创建我在 MS Access VBA 中开始的项目。它基本上是在 Web 应用程序中抓取一系列页面。您可能已经猜到我在 LoadCompleted 事件中遇到了问题。

我已经搜索并找到了一些关于它的信息,但代码的“流程”仅适用于等待一页加载。例如:

http://social.msdn.microsoft.com/Forums/nn-NO/wpf/thread/52c1bc55-dd41-468c-8759-a42726635d4b

所有代码执行都在 DocumentLoaded 事件中运行,当您只需要导航到一页并执行代码时,该事件就可以正常工作。但我需要为我的应用程序执行一系列这些循环。

如何可靠地等待文档完全加载,同时仍将代码执行保持在同一个 Sub 中并且不锁定 UI 线程?

这是我正在尝试做的基本想法。

  1. 导航到页面
  2. 等待页面完全加载
  3. 做事
  4. 导航到页面
  5. 冲洗,重复

P.S - .NET 对我来说很新,所以请不要让我的大脑出现堆栈溢出;)

谢谢, 布赖恩

-## 编辑##-

这就是我在 VBA 中所做的。这正是我想要做的,只是以“.NET”的方式并且不阻塞 UI 线程:

Dim oIE = New SHDocVw.InternetExplorer

        With oIE
            .Navigate(strURL)
            .Visible = False


           ' loop until the page finishes loading
           Do While oIE.Busy : Loop
           Do While oIE.ReadyState <> 4 : Loop

           'Code goes here to read DOM, get fields and click a button (logging in to site)
           'My code execution is done and now I'm ready to go to the next page and read the DOM

           .Navigate(strURL)

        End With

。 . . .

就是这样。重复 n 次。我与每个 DOM 的交互有很大不同。

【问题讨论】:

    标签: .net wpf vb.net user-controls webbrowser-control


    【解决方案1】:

    我会在LoadCompleted 处理程序的末尾再次调用Navigate。然后,我猜,使用窗口范围的变量来跟踪您的目标 URL。

    List<string> _urls;
    int _i = 0;
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        _urls = new List<string>() { url1, url2, url3 };    // URLs to navigate
        webBrowser1.LoadCompleted += webBrowser1_LoadCompleted;
        webBrowser1.Navigate(_urls[_i]);
    }
    void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
    {
        // do stuff
    
        i++;
        var nextUrl = _urls[i];
        webBrowser1.Navigate(nextUrl);
    }
    

    编辑

    也许这样的东西会更合适。在每个循环之后,您可以设置下一个 URL 及其处理程序。

    class NavIteration
    {
        public string Url { get; set; }
        public delegate void HandleResult(object sender, NavigationEventArgs e);
        public HandleResult ResultHandler { get; set; }
    }
    
    NavIteration CurrentIteration;
    
    void setNextIteration()
    {
        CurrentIteration = null;
        CurrentIteration = new NavIteration() { 
            Url = someurl, 
            ResultHandler = (sender, e) => {
                // handle
            }
        };
    }
    
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        webBrowser1.LoadCompleted += webBrowser1_LoadCompleted;
        setNextIteration();
        webBrowser1.Navigate();
    }
    
    void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
    {
        CurrentIteration.ResultHandler(sender, e);
        setNextIteration();
        webBrowser1.Navigate(CurrentIteration.Url);
    }
    

    【讨论】:

    • dbaseman,感谢您的回复。不幸的是,我导航到的 URL 是未知的。也就是说,需要的 URL 数量和 URL 本身是在每个“循环”之后动态生成的
    • @brian gotcha。原则上不一样吗?只需调用 getNextUrl() 的一些实现就可以了?
    • 啊,我明白了。您是说我可以在遍历列表时即时将项目添加到列表中。但是我对每个 URL 的操作(代码)是不同的。我只是要有一个巨大的 SELECT..Case 来处理每个 URL 吗?由于在列表中的下一页之前我不知道 URL,我如何将浏览器的当前 URL 匹配到适当的代码块?我希望我问的问题足够清楚。感谢您抽出时间帮助我。谢谢。
    • 没有问题...我想这取决于。每个 URL 的代码是否完全不同?或者您可以编写一个带有一些参数的函数来处理所有情况吗?或者您可以根据某种类别对处理程序代码进行分组吗?
    • 完全不同 - 有时我只是在读取值,有时我正在发送输入或调用 javascript 函数。我很震惊,没有比这更好的选择了..
    【解决方案2】:

    也许我很遥远,但我会在BackGroundWorker 中“做点什么”。让主线程除了查找页面之外什么都不做。如果“do stuff”比 find 慢,那么下一个限制 find。

    您是否考虑过 WebClient 下载到 String 或 Byte 数组,然后转换为 DOM。 IE中有什么你需要的吗?

    【讨论】:

    • 嗨,Blam - 在这种情况下,“东西”是从浏览器 DOM 中抓取数据。我看不出 BGW 如何提供帮助。无论它在哪个线程上运行,它仍然需要等待 IE 完全加载。必须多次调用 WebBrowser 并将其全部转储到事件处理程序上,这对我来说是一个挑战。
    • @brian 查看更新的答案。如果你看不到 BGW 上的东西有什么帮助,那么我怀疑我能帮助你。
    • 也许我只是不明白你在提议什么?我进入 .NET 已经 5 天了。因此,在按钮的单击事件中,我对其进行编码以导航到页面。然后“运行”一个 BGW 来读取页面的 dom。我仍然遇到同样的问题。在浏览器完成加载之前,我无法开始读取 DOM。这不是同时做两件事的问题。它正在做一件事并在我进行下一件事之前确认它已完成,然后冲洗/重复。我不想在此过程中锁定我的应用程序,但此时我什至不在乎这是否意味着让它做我想做的事。
    • 我正在与网站上的每个页面进行交互。所以我不能只是把 DOM 拉下来。我需要为要访问的每个页面阅读元素、点击控件等。
    猜你喜欢
    • 2013-10-31
    • 2019-03-06
    • 2018-11-07
    • 2011-12-23
    • 2013-04-02
    • 2021-02-05
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多