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

使用 ASP.NET 中的 HtmlAgilityPack (HAP) 抓取 HTML DOM 元素

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (29投票s)

2013年9月26日

CPOL

4分钟阅读

viewsIcon

151268

downloadIcon

3845

抓取/解析网站的 DOM 元素。

简介(什么是屏幕抓取?)

解析网站的 HTML 也被称为屏幕抓取。这是一个访问外部网站信息(信息必须是公开的——公共数据)并根据需要进行处理的过程。例如,如果我们想获取不同网站上诺基亚 Lumia 1020 的平均评分,我们可以从所有网站上抓取评分,然后在我们的代码中计算平均值。所以我们可以说,作为一个一般的“用户”,你能获得的“公共数据”,都可以使用 HTML Agility Pack 轻松抓取。 

背景

以前抓取网站比较困难,因为整个 DOM 元素都以字符串形式下载。所以处理字符串并查找单个节点,通过迭代并匹配标签和属性来指定你的需求,并不是一件愉快的事情。渐渐地,方法得到了改进,现在使用 HtmlAgilityPack 库变得非常容易。这就是为什么本文将为你提供一个关于如何开始使用 HAP 的简单演示。

你需要具备编程基础,并且必须知道如何使用 C# 和 ASP.NET 编写代码。  

工作原理

在 HTML Agility Pack 出现之前,我们不得不使用 .NET Framework 中不同的内置类来从网站中提取 HTML。但现在我们不必使用这么多类,而是使用 HAP 库,并命令它为我们完成任务。

这很简单。你的代码将向服务器发出 HTTP 请求,并解析/存储返回的 HTML。 

首先,HAP 会创建一个特定网站解析后的 HTML 的 DOM 视图。然后,只需要几行代码就可以让你遍历 DOM,按你喜欢的方式选择节点。使用 XPath 表达式,HAP 还可以为你提供特定的节点及其属性。HAP 还包含一个下载远程网站的类。

让我们开始吧

在此示例中,我们将解析特定网页的所有链接,并在我们的网页中使用 HtmlAgilityPack 显示它们。那么,让我们开始吧。

  1. 运行 Visual Studio 2012
  2. 转到 文件 -> 新建 -> 项目,从 Visual C# 模板中选择 Web,然后在右侧选择 ASP.NET 空 Web 应用程序。将应用程序命名为 HTMLAgilityPackStartUp,然后单击确定
  3. 解决方案资源管理器中,右键单击项目中的引用。然后单击管理 Nuget 程序包
  4. 将出现管理 Nuget 程序包窗口。单击右侧的搜索栏并搜索 HtmlAgilityPack。它将为你提供与该名称相关的库和扩展。在窗口的中间标签页中,你会在第一行找到 HtmlAgilityPack 库。单击安装。它将下载并安装库到你的项目中,安装完成后单击确定
  5. 检查库是否已添加到引用中。

  6. 现在让我们创建一个新的 Web Form,并将其命名为 MyScraper.aspx,然后单击添加
  7. 我们将按照以下方式编辑 MyScraper.aspx 文件,添加一些标签、一个文本框和一个按钮,然后保存。 
  8. <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MyScraper.aspx.cs" Inherits="HTMLAgilityPackStartUp.MyScraper" %> 
    <!DOCTYPE html> 
    <html xmlns="http://www.w3.org/1999/xhtml"> 
       <head runat="server"> <title></title> 
       </head> 
       <body>     
          <form id="form1" runat="server"> 
             <div> 
    	    <asp:Label ID="InputHereLabel" runat="server" Text="Input Here" /> 
    	    <asp:TextBox ID="InputTextBox" runat="server" /> <br /> 
    	    <asp:Button ID="ClickMeButton" runat="server" Text="Click Me" OnClick="ClickMeButton_Click" /> <br /> <br /> 
                <asp:Label ID="OutputLabel" runat="server" /> 
    	</div> 
          </form> 
       </body> 
    </html> 

  9. 切换到 MyScraper.aspx 页面的设计视图,单击 ClickMeButton 按钮,按 f4 切换到属性窗口,然后单击事件选项卡,然后双击 Click Action。这将在 MyScraper.aspx.cs 中创建一个处理程序。
  10. 现在,我们想获取一个特定网页的所有链接。为此,请在 MyScraper.aspx.cs 页面中添加以下 using 语句 using HtmlAgilityPack;,并按以下方式更新 ClickMeButton_Click 处理程序: 
  11. using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using HtmlAgilityPack; 
    
    namespace HTMLAgilityPackStartUp
    {
       public partial class MyScraper : System.Web.UI.Page
       {
          protected void Page_Load(object sender, EventArgs e)
          {
          }
          protected void ClickMeButton_Click(object sender, EventArgs e)
          {
    	 var getHtmlWeb = new HtmlWeb();
    	 var document = getHtmlWeb.Load(InputTextBox.Text);
    	 var aTags = document.DocumentNode.SelectNodes("//a");
    	 int counter = 1;
    	 if (aTags != null)
    	 {
    		 foreach (var aTag in aTags)
    		 {
    		    OutputLabel.Text += counter + ". " + aTag.InnerHtml + " - " + aTag.Attributes["href"].Value + "\t" + "<br />";
    		    counter++;
    		 }
    	 }
          }
       }
    }   
     

    代码解释 (MyScraper.aspx.cs)

var getHtmlWeb = new HtmlWeb(); 

获取 HtmlWeb() 的实例,使用 Load 方法获取 URL 的 DOM 元素。

var document = getHtmlWeb.Load(InputTextBox.Text); 

使用 Load 方法获取 DOM 元素。

var aTags = document.DocumentNode.SelectNodes("//a");

在将 DOM 元素以 HtmlDocument 格式获取后,我们使用 DocumentNode 来选择特定标签(在本例中是“a”标签)的所有节点,使用 SelectNodes

int counter = 1;

我们设置一个计数器来计算找到的链接数量。

if (aTags != null)
{
    foreach (var aTag in aTags)
    {
       OutputLabel.Text += counter + ". " + aTag.InnerHtml + " - " + 
         aTag.Attributes["href"].Value + "\t" + "<br />";
       counter++;
    }
}

然后我们检查节点是否存在。如果存在,那么我们遍历节点并打印该节点(<a> 标签)的 InnerHtml 和该节点的“href”属性值,每次找到新节点时都会增加该值。

之后,按 F6 生成项目,按 F5 运行。输入以下内容 https://htmlagilitypack.codeplex.com/,然后单击Click Me。你将看到它将提取该 URL 中 <a> 标签的所有 hrefinnerHtml,输出如下。



因此,这就是我们如何将 HtmlAgilityPack 与 ASP.NET 结合使用来解析网页中的 DOM 元素。你可以使用内置的类和函数以不同的格式解析所有标签,将它们作为 ParentNode 或 ChildNodes 或以许多其他方式遍历。HAP 为你提供了更多的灵活性来浏览 DOM 元素并选择你想要操作的元素。希望你喜欢。

技巧

转到 https://htmlagilitypack.codeplex.com/ 并关注论坛和讨论。在我撰写本文时,你在文档标签页中找不到任何帮助。因此,你可以为这个开源项目做出更多更好的贡献。尝试了解 HAP 提供的所有功能和用途。你了解得越多,就能越轻松地进行抓取。

历史 

N/A。

© . All rights reserved.