例子三 修改并保存HTML文档
上面两个例子分别演示了如何使用Html Agility包去抓取一个网页并且解析,但有的情况下,也需要修改文档的DOM结构并且保存到磁盘上。这个例子演示的跟前两个有点相象,要求用户输入一个网页的地址,之后抓取网页,并且对以下两个方面进行了修改。
1. 在程序读取文档的同时,使用程序的方法,动态增加一个新的元素结点,使其成为标签的第一个孩子结点。
2. 文档中所有的链接,改变成以新打开窗口的方式打开,这个设置其targer属性为_blank即可。
在修改完代码后,同时把它保存到用户本地的磁盘上。同样,一开始的步骤跟前面两个是一样的:
var document = webGet.Load(url);
接下来,通过Linq语法的扩展方法去查找body元素,下面的代码的意思是:在document结点的所有子孙结点中,查找第一个结点并且它的名称是“body”,如果不存在,则返回null。
.Where(n => n.Name == "body")
.FirstOrDefault();
如果找到body标签后,我们则创建一个新的HTML元素标签,下面的代码创建了一个新的HTML元素标签(变量名为messageElement),并且指定了其样式属性,为这个标指定了其命名div,说明要创建的是一个
标签,最后为其指定了inner HTML属性的值,当然最后要把建立好的元素结点插入到body标签的开始:
{
var messageElement = new HtmlNode(HtmlNodeType.Element, document, 0);
messageElement.Attributes.Add("style", "width:95%;border:solid black 2px;background-color:#ffc;font-size:xx-large;text-align:center");
messageElement.Name = "div";
messageElement.InnerHtml = "<p>Hello! This page was modified by the Html Agility Pack!</p><p>Click on a link below... it should open in a new window!</p>";
body.ChildNodes.Insert(0, messageElement);
}
接下来,SelectNodes方法会返回所有
if (linksThatDoNotOpenInNewWindow != null)
{
foreach (var link in linksThatDoNotOpenInNewWindow)
if (link.Attributes["target"] == null)
link.Attributes.Add("target", "_blank");
else
link.Attributes["target"].Value = "_blank";
}
最后,我们调用save方法去保存我们做的修改,在本文中,将其保存在ModifiedPages目录下,并且用guid的方法生成了其文件名,如下代码:
document.Save(Server.MapPath(fileName));
下图显示了运行例子三后的结果,可以看到,我们把页面修改并保存后,在页面的一开始,的确加入了我们要加入的内容,并且你可以试下打开所有页面的链接,都会发现是以新打开链接方式打开的,要注意的是,因为4guysfromrolla网页上使用的都是相对路径,因此图片我们这次没把它们保存下来,所以在这个页面中看不到是正常的。

▲
总结:
本文简单介绍了Html Agility中的基本用法,读者可以继续查看Html Agility文档,去领会学习其中更高级的用法。
标签,之后对其进行遍历,对于集合中的每个标签,查看它是否有target属性,如果没的话,则增加其target属性的值并设置为_blank,如果有的话,则把其值设置为_blank,如下代码: