C# 使用 AngleSharp 解析 HTML
最后修改于 2023 年 7 月 5 日
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# AngleSharp QuerySelectorAll
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?
C# 异步解析 HTML 页面
在下一个例子中,我们异步解析几个 HTML 页面。
using AngleSharp;
using AngleSharp.Dom;
var urls = new[] {
"http://webcode.me", "http://example.com",
"http://httpbin.org", "https://google.com",
"https://rust-lang.net.cn/", "https://golang.ac.cn/",
"https://fsharp.org/", "https://clojure.org/",
"https://perl.net.cn/", "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# 教程。