C#AngleSharp教程展示了如何使用AngleSharp库在C#中解析HTML。
该库还可以解析SVG、MathML或XML。
文档对象模型(DOM)是一种标准的树结构,其中每个节点都包含来自XML结构的组件之一。元素节点和文本节点是两种最常见的节点类型。使用DOM函数,我们可以创建节点、删除节点、更改它们的内容以及遍历节点层次结构。
节点、元素和标签是同义词。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Words</title>
</head>
<body>
<ul>
<li>sky</li>
<li>cup</li>
<li>water</li>
<li>cloud</li>
<li>bear</li>
<li>wolf</li>
</ul>
</body>
</html>
在几个例子中,我们使用这个HTML文件。
C#AngleSharp解析HTML字符串
在第一个示例中,我们从字符串中读取HTML文档。
using AngleSharp; var html = @" <html> <head> <title>My Title</title> </head> <body> <h1>Heading I</h1> <p>Paragraph I</p> <p>Paragraph II</p> </body> </html>"; var config = Configuration.Default; using var context = BrowsingContext.New(config); using var doc = await context.OpenAsync(req => req.Content(html)); Console.WriteLine(doc.Title); Console.WriteLine(doc.Body.InnerHtml.Trim()); Console.WriteLine(doc.FirstChild.NodeName.ToLower()); Console.WriteLine(doc.LastChild.NodeName.ToLower());
我们打印文档的标题、正文以及孩子的名字和姓氏。
var config = Configuration.Default; using var context = BrowsingContext.New(config);
为了设置AngleSharp,我们定义了一个BrowsingContext,我们将Configuration传递给它。
using var doc = await context.OpenAsync(req => req.Content(html));
文档使用OpenAsync加载。
Console.WriteLine(doc.Title);
通过Title属性,我们可以得到文档的标题。
Console.WriteLine(doc.Body.InnerHtml.Trim());
通过Body属性,我们得到文档主体的内部HTML。
Console.WriteLine(doc.FirstChild.NodeName.ToLower()); Console.WriteLine(doc.LastChild.NodeName.ToLower());
我们获取文档的第一个和最后一个子项的名称。
$ dotnet run My Title <h1>Heading I</h1> <p>Paragraph I</p> <p>Paragraph II</p> html html
C#AngleSharpQuerySelectorAll
QuerySelectorAll方法返回文档中与指定选择器组匹配的元素列表。
using AngleSharp;
using AngleSharp.Dom;
var html = @"
<html>
<p>words</p>
<ul>
<li>sky</li>
<li>cup</li>
<li>rock</li>
<li>water</li>
</ul>
</html>";
using var context = BrowsingContext.New(Configuration.Default);
using var doc = await context.OpenAsync(req => req.Content(html));
var els = doc.QuerySelectorAll("li");
foreach (var e in els)
{
Console.WriteLine(e.Text());
}
在示例中,我们获取了所有的li标签。使用Text方法,我们获取节点的内容文本。
$ dotnet run sky cup rock water
C#AngleSharp解析HTML文件
在下面的示例中,我们从HTML文件加载文档。
using AngleSharp;
var html = File.ReadAllText(@"/home/janbodnar/Documents/words.html");
var config = Configuration.Default;
using var context = BrowsingContext.New(config);
using var doc = await context.OpenAsync(req => req.Content(html));
var lis = doc.QuerySelectorAll("li");
foreach (var li in lis)
{
Console.WriteLine(li.InnerHtml);
}
我们使用File.ReadAllText将HTML文件读入一个字符串。然后我们选择所有li标签并打印它们的内部HTML。(在这种情况下,它等同于Text方法。)
C#AngleSharp修改文档
在下面的示例中,我们加载一个HTML文件并对其进行修改。修改后的文档写入磁盘。
using AngleSharp;
using AngleSharp.Text;
var html = File.ReadAllText(@"/home/janbodnar/words.html");
var config = Configuration.Default;
using var context = BrowsingContext.New(config);
using var doc = await context.OpenAsync(req => req.Content(html));
var wli = doc.CreateElement("li");
wli.TextContent = "smile";
var ul = doc.QuerySelector("ul");
ul.FirstElementChild.Remove();
ul.AppendChild(wli);
var p = doc.CreateElement("p");
p.TextContent = $"New paragraph{Symbols.NoBreakSpace}";
doc.Body.AppendChild(p);
File.WriteAllText("/home/janbodnar/words2.html", doc.ToHtml());
在示例中,我们添加了两个元素并删除了一个元素。
var wli = doc.CreateElement("li");
wli.TextContent = "smile";
使用CreateElement创建一个新元素。我们使用TextContent属性设置其内容。
var ul = doc.QuerySelector("ul");
ul.FirstElementChild.Remove();
ul.AppendChild(wli);
我们找到ul元素并使用Remove删除它的第一个子元素。然后我们使用AppendChild附加新创建的元素。
var p = doc.CreateElement("p");
p.TextContent = $"New paragraph{Symbols.NoBreakSpace}";
doc.Body.AppendChild(p);
我们还在正文末尾添加了一段。
File.WriteAllText("/home/janbodnar/words2.html", doc.ToHtml());
修改后的文档使用WriteAllText保存到磁盘。
C#AngleSharp解析HTML页面
在下一个例子中,我们从一个简单的网站加载一个HTML页面。
using AngleSharp;
using AngleSharp.Dom;
var config = Configuration.Default.WithDefaultLoader();
using var context = BrowsingContext.New(config);
var url = "http://webcode.me";
using var doc = await context.OpenAsync(url);
// var title = doc.QuerySelector("title").InnerHtml;
var title = doc.Title;
Console.WriteLine(title);
var pars = doc.QuerySelectorAll("p");
foreach (var par in pars)
{
Console.WriteLine(par.Text().Trim());
}
从页面的HTML文档中,我们得到它的标题和两段的内容。
var config = Configuration.Default.WithDefaultLoader();
为了能够从HTML页面读取,我们调用了WithDefaultLoader方法。
$ dotnet run My html page Today is a beautiful day. We go swimming and fishing. Hello there. How are you?
HTML页面的C#异步解析
在下一个示例中,我们异步解析多个HTML页面。
using AngleSharp;
using AngleSharp.Dom;
var urls = new[] {
"http://webcode.me", "http://example.com",
"http://httpbin.org", "https://google.com",
"https://www.rust-lang.org/", "https://golang.org/",
"https://fsharp.org/", "https://clojure.org/",
"https://www.perl.org/", "https://gnu.org"
};
var config = Configuration.Default.WithDefaultLoader();
using var context = BrowsingContext.New(config);
var docs = new List<Task<IDocument>>();
foreach (var url in urls)
{
docs.Add(context.OpenAsync(url));
}
Task.WaitAll(docs.ToArray());
foreach (var t in docs)
{
var res = t.Result;
Console.WriteLine(res.Title);
res.Dispose();
}
该示例异步加载多个网页并解析它们的标题。
$ dotnet run My html page Example Domain httpbin.org Google Rust Programming Language The Go Programming Language F# Software Foundation Clojure The Perl Programming Language - www.perl.org The GNU Operating System and the Free Software Movement
C#AngleSharp搜索结果
在下一个示例中,我们向Google搜索引擎提交请求并处理结果。
using System.Text.RegularExpressions;
using AngleSharp;
using AngleSharp.Dom;
using AngleSharp.Html.Dom;
using var context = BrowsingContext.New(Configuration.Default.WithDefaultLoader());
using var doc = await context.OpenAsync("https://www.google.com/");
var form = doc.QuerySelector<IHtmlFormElement>("form[action='/search']");
var term = "F# language";
using var res = await form.SubmitAsync(new {q = term});
var links = res.QuerySelectorAll<IHtmlAnchorElement>("a");
foreach (var link in links)
{
var val = link.Attributes["href"].Value;
if (!val.Contains("google"))
{
var rx = new Regex(@"(/url\?q=)([^&]*)(\&)", RegexOptions.Compiled);
var match = rx.Match(val);
if (match.Success)
{
Console.WriteLine(match.Groups[2]);
}
}
}
该示例打印搜索引擎针对给定搜索词返回的所有链接。
var form = doc.QuerySelector<IHtmlFormElement>("form[action='/search']");
我们找到表格。
using var res = await form.SubmitAsync(new {q = term});
表单使用SubmitAsync提交。
var links = res.QuerySelectorAll<IHtmlAnchorElement>("a");
从结果中,我们得到了所有链接。
foreach (var link in links)
{
var val = link.Attributes["href"].Value;
...
我们遍历链接并获取其href属性的内容,其中包含链接。
if (!val.Contains("google"))
我们要排除搜索引擎链接,例如指向条款、隐私和相似性的链接。
var rx = new Regex(@"(/url\?q=)([^&]*)(\&)", RegexOptions.Compiled);
if (match.Success)
{
Console.WriteLine(match.Groups[2]);
}
我们使用正则表达式来处理链接。我们感兴趣的链接以/url?q=前缀开头。搜索引擎在&后缀后附加一些参数到链接。我们将正则表达式分为三组并选择第二组。
$ dotnet run https://fsharp.org/ https://fsharp.org/learn/ https://fsharp.org/specs/language-spec/ https://fsharp.org/about/ https://fsharp.org/use/windows/ https://docs.microsoft.com/en-us/dotnet/fsharp/what-is-fsharp https://medium.com/skills-matter/what-is-the-most-underrated-programming-language-fa... https://www.planetgeek.ch/2020/12/16/c-vs-f/ https://en.wikipedia.org/wiki/F_Sharp_(programming_language) https://en.wikipedia.org/wiki/F_Sharp_(programming_language) https://sk.wikipedia.org/wiki/F_Sharp ...
在本文中,我们使用AngleSharp在C#中解析了HTML文档。
列出所有C#教程。
