【问题标题】:WebBrowser cuts off DocumentTextWebBrowser 切断 DocumentText
【发布时间】:2013-08-17 01:58:12
【问题描述】:

我有一个简单(而且很奇怪)的问题。当我手动将 WebBrowser.DocumentText 属性设置为某个 HTML 字符串时,它会在随机字符后将其切断。我使用的 HTML 是其他页面的纯 HTML,通过 HtmlAgilityPack 下载(在实际应用程序中,我对其进行了一些处理,但即使没有任何处理,也存在错误)。当我在 Internet Explorer 中加载同一页面时,整个页面都正确呈现。

这是一个最小的例子:

const string url = "http://www.zip-codes.com/county/IL-COOK.asp";
var doc = new HtmlWeb().Load(url);

HtmlNode basehref = new HtmlNode(HtmlNodeType.Element, doc, 0) { Name = "base" };
basehref.Attributes.Add("href", url.Substring(0, url.LastIndexOf("/") + 1));
doc.DocumentNode.SelectSingleNode("//head").ChildNodes.Insert(0, basehref);

string html;
using (var writer = new StringWriter()) {
    doc.Save(writer);
    html = writer.ToString();
}

var thread = new Thread(() => {
    var browser = new WebBrowser {
        Location = new Point(0, 0),
        Size = new Size(1920, 1080),
        ScriptErrorsSuppressed = true,
        AllowNavigation = true,
        DocumentText = html
    };
    browser.DocumentCompleted += (sender, e) => {
        Console.WriteLine(html.Length);
        Console.WriteLine(browser.DocumentText.Length);
        Application.ExitThread();
    };
    Application.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();

它输出:

35259
20477

【问题讨论】:

  • 使用 FireBug、IE 或 Chrome 的调试器 (F12) 分析网页的 DOM。也许 HtmlAgilityPack 不像“真正的”浏览器那样运行一些 JavaScript 或严格的内容,这是完全显示所必需的。您知道 HtmlAgilityPack 在后台使用什么 Web 客户端技术以及如何使用吗?
  • @CsabaToth HtmlAgilityPack 只发送一般的HttpWebRequest。无论如何,这不是问题的根源。请注意,(a) HtmlAgilityPack 的字符串比 WebBrowser 的字符串,并且 (b) 字符串在文本中间被截断,在随机字符之后。它不是缺少标签的有效 HTML。它是原始字符串的前缀(IE 尝试尽可能多地修复它并以某种方式部分呈现)。

标签: c# browser html-agility-pack


【解决方案1】:

我在没有Application.ExitThread() 的情况下尝试了您的代码,结果DocumentCompleted 被触发了两次,第二次长度看起来是正确的。因此,您尝试加载的网站可能包含一些动态内容或正在刷新自身。我还没有深入研究它的作用,而是继续删除了所有脚本、样式和 iframe:

    const string url = "http://www.zip-codes.com/county/IL-COOK.asp";
    var doc = new HtmlWeb().Load(url);

    doc.DocumentNode.Descendants()
                    .Where(n => n.Name == "script" || n.Name == "style" || n.Name == "iframe")
                    .ToList()
                    .ForEach(n => n.Remove());

现在DocumentCompleted 被触发一次,文档长度保持一致。

【讨论】:

  • @user3061212,抱歉,我不确定我有没有收到您的问题
  • 如果你使用 new HtmlWeb().Load(url);你有网页,但它不执行 javascript,而不是 WebBrowser
  • @user3061212,确实如此。 Html Agility Pack 不执行 JavaScript,但 here's how you can possibly do this.
【解决方案2】:

我是这样解决的:

const string url = "http://www.zip-codes.com/county/IL-COOK.asp";
var doc = new HtmlWeb().Load(url);

HtmlNode basehref = new HtmlNode(HtmlNodeType.Element, doc, 0) { Name = "base" };
basehref.Attributes.Add("href", url.Substring(0, url.LastIndexOf("/") + 1));
doc.DocumentNode.SelectSingleNode("//head").ChildNodes.Insert(0, basehref);

string html;
using (var writer = new StringWriter()) {
    doc.Save(writer);
    html = writer.ToString();
}

var thread = new Thread(() => {
    var browser = new WebBrowser {
        Location = new Point(0, 0),
        Size = new Size(1920, 1080),
        ScriptErrorsSuppressed = true,
        AllowNavigation = true,
        DocumentText = html
    };
    browser.DocumentCompleted += (sender, e) => {
        Console.WriteLine(html.Length);
        Console.WriteLine(browser.DocumentText.Length);
        //Application.ExitThread();

        if (browser.ReadyState == WebBrowserReadyState.Complete)
        {
                Application.ExitThread();   // Stops the thread
        }
    };
    Application.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();

【讨论】:

    猜你喜欢
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    • 2013-08-25
    • 2016-06-23
    • 2016-06-30
    相关资源
    最近更新 更多