65.9K
CodeProject 正在变化。 阅读更多。
Home

AfterWork C# HTML 解析器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.10/5 (6投票s)

2009年6月11日

公共领域

2分钟阅读

viewsIcon

58486

downloadIcon

2077

实际上,这更像是一个词法分析器,但仍然非常适用于读取 HTML 并构建 DOM 树。

引言

这是对 MIL HTML Parser 的致敬,我曾经多次使用它,但发现它无法读取某些 HTML。

背景

这是一个 HTML 词法分析器,距离一个像样的 HTML 解析器只有一步之遥。基本上,唯一的区别在于,这个分析器生成一系列 HTML 标记,而不构建 HTML 树结构。

它经过良好的训练,可以处理许多读取格式松散的 HTML 页面的情况(在互联网上非常常见)。

使用代码

这里有一些例子,可以快速了解它的工作方式。

在下面的例子中,我们从 eBay 获取一个页面,并查看词法分析器生成的 HTML 标记序列。

public void DemoExampleTest()
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.ebay.com/");
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    string html;
    using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
    {
        html = streamReader.ReadToEnd();
    }
    HtmlReader reader = new HtmlReader(html);
    IndentBuilder tracker = new IndentBuilder();
    HtmlReader.Read(reader, tracker);
    Trace.WriteLine(reader.Builder.ToString());
    // Trace.WriteLine(tracker.ToString());  // << == UNCOMMENT WITH CAUTION!!!
}

/* -- This is what you are likely to see  ---
[TAG_STARTS:<][DTD:!DOCTYPE][WHITESPACE: ][DTD_TOP:html][WHITESPACE: ][DTD_AVAIL:PUBLIC]
[WHITESPACE: ][DTD_FPI:"-//W3C//DTD HTML 4.01 Transitional//EN"][WHITESPACE: ]
[DTD_URL:"http://www.w3.org/TR/html4/loose.dtd"][TAG_ENDS:>][TAG_STARTS:<][NAME:html]
[TAG_ENDS:>][TAG_STARTS:<][NAME:head][TAG_ENDS:>][TAG_STARTS:<][NAME:meta][WHITESPACE: ]
[ATTR:http-equiv][ASSIGN:=][QUOTED_VALUE:"Content-Type"][WHITESPACE: ][ATTR:content]
[ASSIGN:=][QUOTED_VALUE:"text/html; charset=UTF-8"][TAG_ENDS:>][TAG_STARTS:<][NAME:link] ...
--------------------------------------------*/

在下一个例子中,我们使用相同的页面,并对 HTML 语法进行了一些调整。请查看 TokenChaning 事件的处理程序,这是放置构建 HTML 树结构代码的好地方。

public void PracticalExampleTest()
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.ebay.com/");
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    string html;
    using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
    {
        html = streamReader.ReadToEnd();
    }
    HtmlGrammarOptions options = new HtmlGrammarOptions();
    options.HandleCharacterReferences = true;
    options.DecomposeCharacterReference = true;
    options.HandleUnfinishedTags = true;
    HtmlGrammar grammar = new HtmlGrammar(options);
    HtmlReader reader = new HtmlReader(html, grammar);
    reader.Builder.TokenChaning += delegate(TokenChangingArgs args)
    {
        if (args.HasBefore)
        {
            Trace.WriteLine(args.Before.Id + ": " + args.Before.Value);
        }
    };
    HtmlReader.Read(reader, null);
}

关注点

我个人认为,应该存在一个免费的、像样的 HTML 解析器。我花了几天时间才意识到,互联网上没有可以直接在 C# .NET 项目中使用的东西。好吧,让我们尝试改变现状。

历史

这实际上是我最近一直在开发的一个解析器的原型。这意味着它还需要一些额外的开发才能完成。但它已经可以正常工作,并且可以读取您可能遇到的 98% 的 HTML。在某些情况下,它可能会突然停止,但请快速查看 HtmlGrammar 类。所有缺失的链接和状态都可以轻松地在那里添加。

另请参阅

还有一些可能有用的东西您可能会感兴趣

© . All rights reserved.