0

我试图使用网络浏览器进入一些网页并获取一些信息,以便它记住我的登录详细信息。事情一直工作到这里,但是对于多个 url,Web 浏览器文档加载无法按我的意愿正常工作。

我的意图是转到 url-> 等待它加载-> 将所需的数据放入文本中-> 新的 url 和相同的过程。

我使用 for 循环来更改 url,但是当我运行所有 url 时,所有的 url 都一一传递,而不是等到文档加载并写入文本。请帮我。

 private void button1_Click_1(object sender, EventArgs e)
    {

        String text = File.ReadAllText("links.txt");

        var result = Regex.Split(text, "\r\n|\r|\n");
        foreach (string s in result)
        {
            listBox1.Items.Add(s);
        }
        for (int i = 0; i < listBox1.Items.Count; i++)
        {
            this.Text = Convert.ToString(i + 1) + "/" + Convert.ToString(listBox1.Items.Count);
            textBox1.Text += listBox1.Items[i];

            String url = textBox1.Text;
            webBrowser2.ScriptErrorsSuppressed = true;
            webBrowser2.DocumentCompleted += webBrowser2_DocumentCompleted;
            webBrowser2.Navigate(url);

     }
   }

    void webBrowser2_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        string sourceCode = webBrowser2.DocumentText;
        try
        {
           /*someregax expressions to filter text */

            StreamWriter sw = new StreamWriter("inks_info.txt", true);
            sw.Write("url" + "~" + sourceCode + "\n");
            sw.Close();

            textBox1.Text = "";
        }

        catch
        {

            StreamWriter sw = new StreamWriter("inks_fail.txt", true);
            sw.Write(textBox1.Text + "\n");
            sw.Close();

            textBox1.Text = "";

        }
    }
4

2 回答 2

1

您在每个项目的文档加载上都有一个事件处理程序,但在启动第二次导航之前,您不会等待它在第一次导航之后触发。您的 for 循环需要“更加异步”。例如,将项目放入队列并一次请求一个:

Queue<string> _items;
private void button1_Click_1(object sender, EventArgs e)
{        
    String text = File.ReadAllText("links.txt");
    _items = new Queue<string>(Regex.Split(text, "\r\n|\r|\n"));
    webBrowser2.ScriptErrorsSuppressed = true;
    webBrowser2.DocumentCompleted += webBrowser2_DocumentCompleted;
    RequestItem();
}
private void RequestItem()
{
    if (_items.Any())
    {
        var url = _items.Dequeue(); // preprocess as required
        webBrowser2.Navigate(url);
    }
}
void webBrowser2_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    // Handle result
    RequestItem(); // Then request next item
}

您的代码看起来也像使用 UI 元素(如列表框)作为中间变量只是出于逻辑目的而不是显示。您应该从显示(在列表框中显示结果、更新文本框等)中分离出逻辑(使用常规变量、数据结构如列表和请求数据)。不清楚您是否要使用WebBrowsereven - 看起来您只是在下载文本并且应该使用WebClientor HttpClient。然后使用 async/await 代码也可以更简洁:

foreach (var url in urls)
{
     string text = await new WebClient().DownloadStringAsync(url);
     // Handle text
}
于 2013-02-06T07:58:21.027 回答
1

非常简单的答案。WebBorwser 控件不适合这些东西,但这是您要寻找的东西:

WHILE(webBrowser.ReadyState != WebBrowserReadyState.Ready)
{
     Application.DoEvents()
}

就是这样..它不会冻结您的应用程序或让您迷失在代码中,它只是等到它不导航。不客气。

于 2013-02-06T11:38:21.013 回答