在.NET应用程序中,是否有可能在Web浏览器看到它时获得DOM的表示?

时间:2010-11-02 21:27:24

标签: javascript asp.net-mvc

我需要一个服务器端进程才能为网页生成与网页浏览器相同的HTML dom视图(我知道dom表示是特定于浏览器的,所以不要介意非交叉浏览器解决方案)

我需要能够以后的方式回到网页上的用户选择。由于页面的原始HTML与浏览器构建的Dom之间没有牢固的关系,因此至少可以说这很难说!

我现在的想法是,如果我可以在服务器端进程中生成相同的文档视图,那么我可以实现这一点。

有没有人有这方面的经验?

由于

4 个答案:

答案 0 :(得分:2)

好的,不同的角度。 如何使用WebBrowser Control

据我所知,没有什么能阻止Web应用程序添加对System.Windows程序集的引用并使用它。

有点远,但IMO值得尝试!

答案 1 :(得分:1)

你可以实现的最好的方法是使用WebRequest来读取页面的原始响应(HTML输出),并假设它是有效的XHTML将它扔进XmlReader,你手头有DOM,至少是节点。

答案 2 :(得分:1)

我之前使用过一个名为SgmlReader的HTML解析库,它可以很好地将HTML标记变成可用的DOM。如果它总是产生与浏览器产生的DOM相同的DOM,我会感到惊讶。

答案 3 :(得分:1)

好的......为了它的价值,我能够成功地使用WebBrowser控件(是的,来自System.Windows.Forms)来加载远程页面并自由迭代它的DOM。

我面对和摧毁的墙上的砖块在下面。

完整代码,为了举例说明,它显示了远程页面中的所有图像:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
using System.Reflection;
using System.Windows.Forms;
using System.Text;

namespace TestZone
{
    public partial class _Default : System.Web.UI.Page
    {
        private bool waiting = false;
        private WebBrowser browser = null;
        protected void Page_Load(object sender, EventArgs e)
        {
            Thread thread = new Thread(new ParameterizedThreadStart(LoadRemotePage));
            thread.SetApartmentState(ApartmentState.STA);

            waiting = true;
            thread.Start(this);

            while (waiting)
            {
                Thread.Sleep(10);
            }
        }

        private void LoadRemotePage(object sender)
        {
            try
            {
                browser = new WebBrowser();
                browser.Tag = sender;
                browser.Navigate("http://stackoverflow.com/questions/4082249/in-a-net-application-is-it-possible-to-get-a-representation-of-the-dom-as-a-web/4085520");
                browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(browser_DocumentCompleted);
                while (browser.ReadyState != WebBrowserReadyState.Complete)
                    System.Windows.Forms.Application.DoEvents();
                browser.Dispose();
            }
            catch (Exception ex)
            {
                litDebug.Text = "Error while initializing browser control: " + ex.ToString().Replace("\n", "<br />");
                (sender as _Default).waiting = false;
            }
            finally
            {

            }
            //hgcDebug.GetType().InvokeMember("InnerHtml", BindingFlags.SetProperty, null, hgcDebug, new object[] { "done" });
        }

        void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            try
            {
                HtmlElementCollection collection = browser.Document.GetElementsByTagName("img");
                StringBuilder sb = new StringBuilder();
                sb.AppendFormat("Total of {0} images:<br />", collection.Count);
                for (int i = 0; i < collection.Count; i++)
                    sb.AppendFormat("name: {0}, src: {1}<br />", collection[i].GetAttribute("name"), collection[i].GetAttribute("src"));
                litDebug.Text = sb.ToString();
            }
            catch (Exception ex)
            {
                litDebug.Text = "Error while analyzing remote page: " + ex.ToString().Replace("\n", "<br />");
            }
            finally
            {
                ((sender as WebBrowser).Tag as _Default).waiting = false;
            }
        }
    }
}
如果有人好奇的话,

一路颠簸:

  1. 创建WebBrowser控件时出现异常..线程处于错误状态。修复了将代码移动到新线程,将ApartmentState明确设置为STA。
  2. WebBrowser的Document属性为null。修复的第一步是使用DocumentCompleted事件而不是在导航后立即访问文档。 虽然没有运气,但DocumentCompleted从未发生过。为了解决这个问题,我添加了循环,等待ReadyState完成。做完了,但是......
  3. 所有这一切,从新线程中更改文字对实际GUI没有影响..必须在主线程中等待,直到完成所有操作。
  4. 希望有一天能为某人带来便利,如果不是这里的OP。 :)