4

必要なものをすべてロードした WebBrowser で HTML アビリティ パックを使用したい (コード付きのボタンをクリックして、チャネルのすべてのビデオをロードする) (YouTube チャネルをロードし、そのチャネルのすべてのビデオをロードする) .) すべてのビデオの詳細を取得しようとすると (チャネルの最初の 30 個のビデオをリストビューに取得する作業コードがあります)、最初の 30 個のみが表示されますが、すべてのビデオが WebBrowser にロードされています。ページ (すべてのビデオが表示されます) WebBrowser から現在ロードされているものを取得するためにこれを使用しています

ここに画像の説明を入力

ただし、 WebBrowser からロードされたすべてのビデオではなく、最初の 30 個のビデオのみがロードされます。

4

1 に答える 1

5

ターゲット Web サイトが (Youtube のように) AJAX を多用している場合、不可能ではないにしても、ページがすべての動的スクリプトの読み込みと実行を完了したことを判断するのは困難です。window.onloadただし、イベントを処理し、非決定論的な AJAX 呼び出しに 1 ~ 2 秒余分に許可することで、近づくことができます。webBrowser.Document.DomDocument.documentElement.outerHTML次にviaを呼び出してdynamic、現在レンダリングされている HTML を取得します。

例:

private void Form1_Load(object sender, EventArgs e)
{
    DownloadAsync("http://www.example.com").ContinueWith(
        (task) => MessageBox.Show(task.Result),
        TaskScheduler.FromCurrentSynchronizationContext());
}

async Task<string> DownloadAsync(string url)
{
    TaskCompletionSource<bool> onloadTcs = new TaskCompletionSource<bool>();
    WebBrowserDocumentCompletedEventHandler handler = null;

    handler = delegate
    {
        this.webBrowser.DocumentCompleted -= handler;

        // attach to subscribe to DOM onload event
        this.webBrowser.Document.Window.AttachEventHandler("onload", delegate
        {
            // each navigation has its own TaskCompletionSource
            if (onloadTcs.Task.IsCompleted)
                return; // this should not be happening
            // signal the completion of the page loading
            onloadTcs.SetResult(true);
        });
    };

    // register DocumentCompleted handler
    this.webBrowser.DocumentCompleted += handler;

    // Navigate to url
    this.webBrowser.Navigate(url);

    // continue upon onload
    await onloadTcs.Task;

    // artificial delay for AJAX
    await Task.Delay(1000);

    // the document has been fully loaded, can access DOM here
    return ((dynamic)this.webBrowser.Document.DomDocument).documentElement.outerHTML;
}

[編集済み] OPの問題を解決するのに役立つ最後のコードは次のとおりです。

HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(((dynamic)this.webBrowser1.Document.DomDocument).documentElement.ou‌​terHTML); 
于 2013-09-15T09:57:32.970 に答える