0

Web ブラウザーを使用して、いくつかの Web ページにアクセスし、いくつかの情報を取得しようとしています。これにより、ログインの詳細が記憶されます。ここまではうまくいきましたが、複数の URL の場合、Web ブラウザーのドキュメントの読み込みが適切に機能しません。

私の意図は、url->ロードするまで待つ->必要なデータをテキストに取得する->新しいurlと同じプロセスに行くことでした。

for ループを使用して URL を変更しましたが、渡されたすべての URL を 1 つずつ実行すると、ドキュメントが読み込まれてテキストに書き込まれるまで待機しませんでした。私を助けてください。

 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

非常に簡単な答え。WebBorwser コントロールはこのようなものには対応していませんが、探しているものは次のとおりです。

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

それだけです..アプリがフリーズしたり、コードで迷子になったりすることはありません。ナビゲートされなくなるまで待機します。どういたしまして。

于 2013-02-06T11:38:21.013 に答える
1

各アイテムのドキュメント ロードにイベント ハンドラーがありますが、最初のナビゲーションの後に発生するのを待ってから 2 番目のナビゲーションを開始します。for ループは「より非同期」にする必要があります。たとえば、項目をキューに入れ、一度に 1 つずつ要求します。

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 要素 (リスト ボックスなど) を表示ではなく論理的な目的で中間変数として使用しているようにも見えます。ロジック (通常の変数、リストなどのデータ構造を使用してデータを要求する) を表示 (リスト ボックスに結果を表示する、テキスト ボックスを更新するなど) から分離する必要があります。偶数を使用する必要があるかどうかは明確ではありません。WebBrowserテキストをダウンロードしているだけのようで、WebClientorを使用する必要がありますHttpClient。コードは、async/await を使用してよりクリーンにすることもできます。

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