返回博客
指南
Sorin-Gabriel MaricaLast updated on Mar 31, 20262 min read

Apiasp.Net Core 网页抓取:2023年必备指南

Apiasp.Net Core 网页抓取:2023年必备指南

Apiasp.net 核心网络爬虫

网页抓取是一种预先编程的技术,用于从网站中提取海量数据。这些数据大多处于无序状态且为 HTML 格式,但随后会被转换为数据库或电子表格中的结构化信息,以便在其他程序中使用。 

要从网站中提取数据,网络爬虫可通过多种独特方法实现。这些方法包括利用在线服务、特定 API,甚至从零开始编写自己的爬虫代码。您可以在多个网站上以结构化形式访问数据。

尽管这通常是最佳选择,但有些网站要么无法以有序的方式向用户提供海量数据,要么在技术创新方面不够先进。在这种情况下,最好采用网络爬虫技术从网站收集数据。

Python 目前是网络爬虫领域应用最广泛的编程语言。针对网络爬虫,Python 提供了多种可供使用的库。同时,.NET 也可用于网络爬取。我们还可以通过某些第三方 Web API 从众多网站抓取数据。

.NET 中一款流行的网络爬取 API 名为 WebScrapingAPI。最近,他们还推出了适用于网络爬取的 .NET Core 版本。

网页抓取与网页 爬取 的区别

网页抓取与网页爬取的区别 

网络浏览器用于展示互联网上网页的元数据,而互联网蕴含着海量数据。用户可以通过基于浏览器的页面显示,轻松地在网站之间切换并解读数据。 

“网络爬取”和“网页抓取”是用于描述提取网页代码过程的术语。网页抓取是指分析网页并从中获取信息的过程。而通过迭代方式搜索网页链接并获取其内容则称为网络爬取。 

这两项操作均由应用程序执行,因为发现新链接需要进行网页抓取。这两个术语有时被互换使用,均指获取信息的过程。不过,它们的应用场景却多种多样。 

此类知识可在何处、以何种方式应用?

网络上的答案数量甚至超过了网站总数。这一认知可成为开发应用程序的宝贵工具,而掌握此类代码的编写方法还可应用于自动化网页测试。

在本篇博客中,我们将探讨利用浏览器和基础HTTP请求进行网页爬取和数据抓取的两种方法,并分析各自的优缺点。

利用 HTTP 请求和网页浏览器下载网页内容

利用 HTTP 请求和网页浏览器下载网页内容

鉴于当今几乎所有信息都已在线化,您无疑可以在任何编程语言中找到用于发送 HTTP 请求的模块。简单的 HTTP 请求执行迅速,而使用 Firefox 和 Google Chrome 等网页浏览器作为替代方案则耗时更长。 

它们的行为和呈现方式各不相同,这改变了每项操作的执行方式,并使其易于阅读和理解,同时还能考虑网页的样式显示和脚本运行。网页浏览器有时会浪费资源。例如,如果您试图从网页中提取文本并将其下载为纯文本,一个简单的HTTP请求就足够了。

然而,由于 JavaScript 应用极为广泛,许多网站上的内容若不运行该脚本便无法显示。在这种情况下,使用浏览器下载网页内容会更加便捷。

CSS 与 XPath 解析

CSS 与 XPath 解析

XPath 和 CSS 是两种常用的文本解析方法。XPath 作为一种查询标记语言,用于在 XML 和 HTML 文件中识别特定元素。 

二者均具有特定结构,编写查询时可遵循该模式。CSS 选择器是一种通过字符串模式选择元素的手段,因其 CSS 样式应用于 HTML 结构之上,故与 XPath 略有相似。

演示准备

演示准备

这些演示基于 C# 和 .NET Core 3.1 环境。由于这些 API 近期变化不大,因此应可在 .NET 4x 环境中运行。代码库中还包含一个包含三个页面的示例站点(一个 ASP.NET Core MVC 应用程序):

  • 包含简单表格的页面 
  • 包含“隐藏链接”的页面以及 
  • 超时后才显示的按钮

使用 Visual Studio 2022 创建 ASP.NET Core Web API

使用 Visual Studio 2022 创建 ASP.NET Core Web API

借助 .NET 6.0,您可以使用 Visual Studio 2022 开发 ASP.NET Core Web API 应用程序。在 Visual Studio 中,您需要为项目命名并选择 ASP.NET Core Web API 模板。

您可以选择 .NET Core Web API 6.0 框架。此外,您还可以选择 OpenAPI 默认支持。这将为项目生成 OpenAPI 元数据。 

此处列出的 API 应通过 NuGet 包管理器进行安装。

针对静态页面

针对静态页面

设置

设置

如果您使用 C#,那么您很可能已经在使用 Visual Studio。本文将使用一个基于 MVC(模型-视图-控制器)的 .NET Core Web 应用程序项目。 

创建新项目后,请使用 NuGet 包管理器安装本指南中所需的全部库。

要在 NuGet 中下载这些包,请选择“浏览”选项,然后输入“HTML Agility Pack”。

安装包后,您即可继续操作。借助此包,可以轻松解析获取的 HTML 表格,以定位您想要保存的标签和数据。 

在通过 Visual Studio 编写爬虫代码之前,必须在代码中引入以下 API:

使用 C# 向网页发送 HTTP 请求

使用 C# 向网页发送 HTTP 请求

假设有一个示例项目,要求您从维基百科中搜寻知名计算机程序员的详细信息。如果维基百科上没有相关条目,那它也就称不上是维基百科了,对吧?

 https://en.wikipedia.org/wiki/list-of-programmers 

该文章中列出了开发者名单,并附有指向每位开发者维基百科页面的超链接。为了后续使用,您可以抓取该列表并将数据保存为 CSV 格式(例如,Excel 可以轻松处理这种格式)。

在线网页抓取的核心思路是:定位包含所需数据的网站,使用 C# 抓取信息,并保存以备后用。这只是网页抓取所能实现的众多简单应用之一。

在更复杂的项目中,可利用顶级分类页面的超链接来爬取网页。不过,在接下来的示例中,我们将专注于该特定的维基百科页面。

使用 .HttpClient 获取 HTML .NET Core Web API

使用 .HttpClient 获取 HTML .NET Core Web API

.NET 内置的 HTTP 客户端名为 HttpClient,默认即可使用。由于 Net.HTTP 命名空间已涵盖所有功能,因此无需任何独立的第三方库或插件。此外,它还原生支持延迟调用。

以下示例展示了如何通过 GetStringAsync() 以异步、非阻塞的方式轻松获取任意 URL 的内容

private static async Task<string> CallUrl(string full URL)

{

HttpClient client = new HttpClient();

var response = await client.GetStringAsync(full URL);

return response;

}

您只需创建一个全新的 HttpClient 对象,调用 GetStringAsync(),"等待"其完成,然后将结果返回给调用方。现在该功能已集成到控制器类中,您可以在 Index() 方法中直接调用 CallUrl(),无需额外操作。让我们来实现一下。

public IActionResult Index(){

string url = "https://en.wikipedia.org/wiki/List_of_programmers";

var response = CallUrl(url).Result;

return View();}

在此,我们在 URL 中指定了维基百科的地址,通过 CallUrl() 调用该方法,并将返回值保存在变量中。

好了,发送 HTTP 请求所需的代码已经完成。虽然我们尚未对其进行处理,但立即运行代码是个绝佳的主意,这样可以确保接收到维基百科的 HTML 内容,而非出现任何错误。

为此,我们首先在 Index() 方法中的 return View() 处设置一个断点。这将确保您能够通过 Visual Studio 调试器界面查看结果。

通过从 Visual Studio 工具栏中选择“运行”选项,您可以测试上述代码:在断点处,Visual Studio 将暂停,允许您查看应用程序的当前状态。

将鼠标悬停在变量上会显示服务器返回了一个有效的 HTML 页面,这表明我们已准备就绪。如果您从上下文菜单中选择“HTML 可视化器”,将看到该 HTML 页面的预览。

HTML 解析

HTML 解析

现在是时候解析已获取的 HTML 表格了。例如,一款广受欢迎的解析器套件 HTML Agility Pack 可以轻松与 LINQ 集成。

在解析 HTML 表格之前,您必须先了解页面的结构,以便精确定位需要提取的元素。此时,浏览器的开发者工具将再次派上用场,因为它们允许您全面检查 DOM 树。

从维基百科页面中我们可以看到,目录中的链接数量众多,因此我们无需处理这些链接。此外还有其他一些链接,其中部分链接(如编辑链接)对于我们的数据收集并非绝对必要。 

进一步分析后,我们发现每个目标链接都位于 li> 父元素内。根据 DOM 树,我们现已确认 li> 元素既用于页面上的目录表,也用于我们实际需要的链接组件。

由于我们实际上并不需要内容表格,因此必须确保将这些 `li>` 元素过滤掉。幸运的是,它们拥有独立的 HTML 类名,因此我们可以在代码中轻松忽略任何带有 `section` 类名的 `li>` 元素。

现在开始编码!我们将首先在控制器类中添加 ParseHtml 方法()。

在此,我们首先创建一个 HtmlDocument 实例,然后通过 CallUrl() 上传之前下载的 HTML 页面。现在我们拥有了页面的有效 DOM 表示,可以开始进行抓取了。

  • 通过 Descendants() 获取所有 li> 子元素
  • 为了过滤掉使用上述 HTML 类的项目,我们利用 LINQ(Where())。
  • 在我们的 wikiLink 字符串列表中,我们遍历 (for each) 所有链接,并将它们的 (relative) URL 保存为相对 URL。

我们将字符串列表返回给调用方。

XPath

XPath

值得注意的是,我们本不必逐个选择元素。我们这样做只是为了树立一个好的示例。

在实际程序中,应用 XPath 查询会更加实用。这样,我们的整个选择过程就可以用一句话来描述。

与我们的常规方法类似,这将选择任何不包含指定类(not(contains()))的 li> 元素。

创建文件以导出抓取的数据

创建文件以导出抓取的数据

HTML 表格内容已从维基百科下载,并解析/处理为 DOM 树,所有需要的链接均已成功提取。因此,我们现在拥有了该页面中超链接的完整列表。

接下来应将这些链接导出为 CSV 文件格式。为了将总列表中的信息写入文件,我们将创建一个名为 WriteToCsv() 的新方法。完整的实现过程如下所示。 

该方法会在本地硬盘上创建名为“links.csv”的文件,并将提取的超链接保存其中。因此,利用.NET框架的原生API将数据写入本地磁盘文件。 

结论

结论

借助 WebScrapingAPI 等工具,构建爬虫项目并快速收集所需信息变得非常简单。总体而言,C# 和 .NET 包含所有必要的资源和库,可助您实现自己的数据抓取工具。

关于如何避免被服务器封禁或限制访问速率,我们仅在此简要提及。通常,阻碍网络爬虫工作的往往不是技术限制,而是其他因素。

如果您更希望专注于数据本身,而非处理用户代理、速率限制、代理服务器和 JavaScript 难题,不妨了解 WebScrapingAPI 的尖端功能。 

关于作者
Sorin-Gabriel Marica, 全栈开发工程师 @ WebScrapingAPI
Sorin-Gabriel Marica全栈开发工程师

索林·马里卡(Sorin Marica)是 WebScrapingAPI 的全栈及 DevOps 工程师,负责开发产品功能并维护确保平台平稳运行的基础设施。

开始构建

准备好扩展您的数据收集规模了吗?

加入2,000多家企业,使用WebScrapingAPI在无需任何基础设施开销的情况下,以企业级规模提取网络数据。