web-dev-qa-db-fra.com

Comment obtenir un rendu HTML (traité par Javascript) dans le contrôle WebBrowser?

J'ai une page ASP.NET et une classe personnalisée qui récupère la page Web spécifiée et renvoie le corps de cette page.

protected String GetHtml()
{
          Thread thread = new Thread(new ThreadStart(GetHtmlWorker));
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    thread.Join();
    return docHtml;
}

protected void GetHtmlWorker()
{
    using (WebBrowser browser = new WebBrowser())
    {

                browser.ScriptErrorsSuppressed = true;
        browser.Navigate(_url);

        // Wait for control to load page
        while (browser.ReadyState != WebBrowserReadyState.Complete)
            Application.DoEvents();

        docHtml = browser.DocumentText;
    }

Mais ce dont j'ai besoin - c'est obtenir DOM html, au lieu de source., Parce que je fais quelques opérations supplémentaires sur DOM par jQuery.

14
Denis Olifer

Voici une solution que j'ai trouvée pour obtenir le rendu HTML (DOM) après l'exécution de javascript:

Placez un contrôle WebBrowser nommé webBrowser1 sur le formulaire de la classe Form1.

[Form1.cs [Design]]

Ensuite, pour utiliser le code:

[Form1.cs]

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WebBrowserTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.webBrowser1.ObjectForScripting = new MyScript();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            webBrowser1.Navigate("http://localhost:6489/Default.aspx");
        }

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            webBrowser1.Navigate("javascript: window.external.CallServerSideCode();");
        }

        [ComVisible(true)]
        public class MyScript
        {
            public void CallServerSideCode()
            {
                var doc = ((Form1)Application.OpenForms[0]).webBrowser1.Document;
            }
        }
    }
}

Remplacez le paramètre webBrowser1.Navigate (" http: // localhost: 6489/Default.aspx ") dans Form1_Load par la page dont vous souhaitez obtenir le DOM après le traitement par javascript.

Vous pouvez accéder au DOM modifié dans la méthode CallServerSideCode (), par exemple:

doc.GetElementById("myDataTable");

Ou vous pouvez accéder au code HTML rendu comme ceci:

var renderedHtml = doc.GetElementsByTagName("HTML")[0].OuterHtml;
16

Comme George l'a dit dans l'un des commentaires, en théorie, vous pouvez obtenir le DOM dans webBrowser1_DocumentCompleted en utilisant simplement:

webBrowser1.Document.GetElementsByTagName("HTML")[0].OuterHtml;
6
jimmyjudas

D'abord un petit fond. J'ai essayé de récupérer des informations d'une page Web. Le contenu de cette page Web est dynamique. Ce que je veux dire par dynamique, c'est que la page Web charge plus d'informations lorsque vous faites défiler l'écran jusqu'au bas de la page. Le contenu HTML change lorsque vous faites défiler la page vers le bas. Malheureusement, l’objet Navigateur Web ne met pas ces informations à jour automatiquement. Le document d'origine qu'il a d'abord chargé via la fonction webbrowser.navigate est toujours présent. Les informations mises à jour sont disponibles pour la HTMLElementCollection.

Le code suivant n'a pas fonctionné pour moi.

webBrowser1.Document.GetElementsByTagName("HTML")[0].OuterHtml

J'ai cassé la déclaration ci-dessus comme suit

    Dim eCollections As HtmlElementCollection
    Dim strDoc As String
    eCollections = WB.Document.GetElementsByTagName("HTML")
    strDoc = eCollections(0).OuterHtml

Travaillé comme un charme. J'espère que cela aide aussi quelqu'un.

2
DeltaGuy

Une autre solution consisterait à définir une minuterie sur le formulaire, puis lorsque la minuterie sera atteinte, la page sera restituée et vous pourrez analyser la page. 

0
JeffT