一个犀利的 HTML 解析器
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
Less.Html
Test
Test4
.gitattributes
.gitignore
LICENSE.txt
Less.Html.sln
README.md

README.md

一个犀利的 HTML 解析器 —— Less.Html

我写了这个解析器之后才知道,原来 C# 写的 html 解析器有很多。但是因为我没有参照别人的做法,Less.Html 有一个特点,就是它的用法是最接近 jQuery 的。我刻意模仿了 jQuery。比如我写的 示例一

var q = HtmlParser.Query(testHtml);
foreach (Element i in q("td"))
{
    if (!q(i).find("table").hasElement)
    {
        Console.WriteLine(i.textContent);
    }
}

解析之后返回的 q 对象,等同于 jQuery 的 $,因为 C# 不支持用 $ 做变量名,所以我用 q 代替。foreach 循环的部分,在 jQuery 的写法应该是:

for(var i = 0; i < $("td").length; i++)

其实在 Less.Html 里面,同样可以这样写,jQuery 不能使用foreach 的原因是,它会枚举对象的属性,C# 没有这个烦恼,所以我做了些改进。if 条件部分,q 和 jQuery 的 $ 一样,是可以传入 Element 类型的,然后调用的 find 方法,作用也是和 jQuery 一样的。hasElement 这个属性,实际上就是 length > 0 的判断,是我写的一个扩展属性,当然,你在 jQuery 里面也可以通过 prototype 做同样的事情。输出部分,textContent 是 HTML DOM 标准的一个方法,作用是获取节点及其后代的文本内容,这和你在编写浏览器运行的 javascript 是一样的。

Less.Html 从解析核心到 DOM、选择器都是我手写的,没有任何依赖项,编译之后只有两个 dll:

其中一个是我的基础类库,也是开源的。

示例一代码:GitHub    码云

项目代码:GitHub    码云

NuGet:
https://www.nuget.org/packages/Less.Html

我当时写这个解析器是因为要做网页爬虫,核心三天写完就能用了,并用来解析了几百万个网页,可用性上是没有问题的。后来我觉得 Razor 语法还是不够好,于是我改进了这个解析器,加上了选择器和操作 html 文档的方法,制作了我自己的视图引擎 QPage。我的个人博客就是使用这个引擎写的:

https://www.nuget.org/packages/QPage/

QPage 在添加文档之后,也会开源。

后来我在网上知道了 csQuery、Jumony 这些解析器的作者,都会把自己的解析器做成视图引擎,我开始觉得在服务器端解析文档,而不是拼接文档,应该是未来的趋势。

以下是 Less.Html 支持的选择器:

选择器 实例 选取
* q("*") 所有元素
#id q("#lastname") id="lastname" 的元素
.class q(".intro") 所有 class="intro" 的元素
element q("p") 所有 <p> 元素
:first q("p:first") 第一个 <p> 元素
:last q("p:last") 最后一个 <p> 元素
[attribute] q("[href]") 所有带有 href 属性的元素
[attribute=value] q("[href='#']") 所有 href 属性的值等于 "#" 的元素
:checkbox q(":checkbox") 所有 type="checkbox" 的 <input> 元素
:eq(index) q("ul li:eq(3)") 列表中的第四个元素(index 从 0 开始)
:gt(no) q("ul li:gt(3)") 列出 index 大于 3 的元素
:lt(no) q("ul li:lt(3)") 列出 index 小于 3 的元素

以及它们的组合使用,比如 .class element.class 或者 .class.class,暂时不支持 .class>.class 这种。

因为时间紧迫,加上对我来说够用了,我并没有实现所有的 css3 选择器,而是根据需要逐步添加,添加了新的选择器我会更新上面的表格。

下面是我写的一些使用示例:

示例一:获取嵌套元素中的正确内容
示例二:以 Less.Html 做视图引擎
示例三:与 WebClient 的配合使用,以抓取 CSDN 论坛内容为例
示例四:与 WebBrowser 的配合使用,以抓取京东手机价格为例
示例五:使用方法详解

如果你实在不想用 Less.Html,我可以介绍一些其他选择:

Html Agility Pack,这个应该是最早的一个,我当时没有用,是因为网上有人说有容错性的问题,如果一个标签没有结束,解析的结果和浏览器不一致。不过这个项目现在都还有维护,我想应该有所改进的。

CsQuery,两年前就没有维护了,网上说这个项目有很好的 css 选择器。我看了介绍,它使用的是 Gecko 的解析器,如果是这样的话,可用性和速度都是有保证的。

AngleSharp,我看了一下介绍,这个项目还有 GUI,应该是功能最强大的一个吧。

Jumony,国产。如果我自己没有写的话,我会使用这个,因为有中文的说明。