网络抓取与网络爬虫的区别
网络浏览器用于展示互联网上网页的元数据,而互联网蕴含着海量的数据。用户只需通过浏览器显示的页面,即可在各个网站之间自由浏览并解读数据。
“网络爬行”和“网页抓取”是用于描述提取网页代码过程的术语。网页抓取是指分析网页并从中获取信息的过程。而通过迭代方式搜索网页链接并获取其内容的过程则称为网络爬行。
这两项操作都是由应用程序执行的,因为发现新链接需要进行网页抓取。这两个术语有时被互换使用,都指获取信息的过程。不过,它们的用途却多种多样。
这种知识可以如何应用?又可以在哪些地方应用?
网上的答案数量甚至比网站数量还要多。这一洞见可以成为开发应用程序的有力工具,而掌握编写此类代码的方法,也可应用于自动化网页测试。
在本篇博客中,我们将探讨两种利用浏览器和基础 HTTP 请求进行网页爬取和数据抓取的方法,并分析各自的优缺点。
利用 HTTP 请求和网页浏览器下载网页内容
鉴于如今几乎所有事物都已实现在线化,无论使用哪种编程语言,你都能轻松找到用于发送 HTTP 请求的模块。简单的 HTTP 请求处理起来很快。相比之下,使用 Firefox 和 Google Chrome 等网页浏览器则需要更长时间。
它们的行为方式和呈现形式各不相同,从而改变了各项操作的实现方式,使其易于理解和使用,并能适应网页的显示样式和运行脚本。网络浏览器有时会浪费资源。例如,如果你只是想从网页中提取文本并将其下载为纯文本,一个简单的HTTP请求就足够了。
尽管如此,由于 JavaScript 的广泛应用,许多网站上的内容如果不运行 JavaScript 就无法显示。在这种情况下,使用浏览器可以更方便地下载网页内容。
CSS 和 XPath 解析
XPath 和 CSS 是两种常用的文本解析方法。XPath 是一种查询标记语言,用于在 XML 和 HTML 文件中定位特定元素。
每个选择器都包含特定的结构,编写查询时可以遵循这种模式。CSS 选择器是一种通过字符串模式选择元素的手段,与 XPath 略有相似之处,因为 CSS 样式是应用于 HTML 结构之上的。
准备演示
这些示例使用了 C# 和 .NETCore 3.1 环境。由于这些 API 近期变化不大 ,因此它们在 .NET4x 环境下也应能正常运行 。该代码库中还包含了一个包含三个页面的示例站点(一个 ASP.NETCore MVC 应用程序):
- 包含简单表格的页面
- 包含“隐藏链接”的页面以及
- 一个仅在超时后显示的按钮
使用 Visual Studio 2022 开发 ASP.NET Core Web API
借助 .NET6.0,可以使用 Visual Studio 2022 开发 ASP.NETCore Web 应用程序 API。在 Visual Studio 中,您必须为项目指定一个有效的名称,并选择 ASP.NETCore Web 应用程序 API 模板。

您可以选择 使用 .NET Core Web API 6.0 框架。此外,您还可以选择启用 OpenAPI 默认支持。对于该项目,这将生成 Sass 元数据。
此处列出的 API 应通过 NuGet 包管理器进行安装。
- HtmlAgilityPack
- Microsoft.EntityFrameworkCore.SqlServer
- Microsoft.EntityFrameworkCore.Tools
适用于静态页面
设置
使用 C# 向网页发送 HTTP 请求
假设有一个示例项目,要求你查阅维基百科,以获取关于知名计算机程序员的详细信息。如果维基百科上没有相关条目,那它也就称不上是维基百科了,对吧?
https://en.wikipedia.org/wiki/list-of-programmers
该文章中列出了开发者名单,并附有指向每位开发者维基百科页面的超链接。为了日后使用,您可以抓取该列表并将数据保存为 CSV 格式(例如,Excel 可以轻松处理这种格式)。
网络爬虫的核心原理在于:定位包含所需数据的网站,使用 C# 爬取信息,并将其保存以备后用。这只是网络爬虫能实现的众多简单应用之一。
在更复杂的项目中,可以利用顶级分类页面上的超链接来爬取网页。不过,在接下来的示例中,我们将重点关注那个特定的维基百科页面。
使用 .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(完整 URL);
返回响应;
}
你只需创建一个全新的 HttpClient 对象,调用 GetStringAsync() 方法,"等待" 它执行完毕,然后将结果返回给调用方。现在,既然该功能已集成到控制器类中,你就可以直接在 Index() 方法中调用 CallUrl(),无需额外操作。让我们来实现一下。
public IActionResult Index(){
字符串 url = "https://en.wikipedia.org/wiki/List_of_programmers";
var response = CallUrl(url).Result;
return View();}
在此,我们在 URL 中指定维基百科的 URL,通过 callUrl() 调用它,并将返回值保存在因变量中。
好的,发送 HTTP 请求所需的代码已经编写完成。虽然我们尚未对其进行处理,但最好立即运行这段代码,以确保能成功接收维基百科的 HTML 内容,避免出现任何错误。
为此,我们首先要在 Index() 方法中,在 return View() 处添加一个暂停点。这样可以确保您能够通过 Visual Studio 调试器界面查看结果。
通过在 Visual Studio 工具栏中选择“运行”选项,您可以测试上述代码:当到达断点时,Visual Studio 将会暂停,从而让您查看应用程序的当前状态。
将鼠标悬停在该变量上会显示服务器返回了一个有效的 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)其中的链接,并将它们的(相对)URL 保留为相对 URL。
我们将字符串列表返回给调用方。
XPath
我们本不必逐一选择这些元素,这一点值得注意。我们之所以这样做,只是为了树立一个好榜样。
在实际程序中,使用 XPath 查询会实用得多。这样一来,整个筛选过程就可以用一句话来完成。
与我们的常规操作类似,这将选择所有不包含指定类名的 (//) li> 元素(not(contains()))。
创建用于导出抓取数据的文件
结论
借助WebScrapingAPI 等工具,构建爬虫项目并快速收集所需信息变得非常简单。总体而言,C# 和 .NET 提供了所有必要的资源和库,助您实现自己的数据抓取工具。

关于如何避免被服务器封禁或降低请求速率,我们此前仅简要提及过相关方法。通常而言,阻碍网络爬虫工作的往往并非技术限制,而是其他因素。
如果您更希望专注于数据本身,而非处理用户代理、速率限制、代理服务器和JavaScript相关的问题,不妨了解一下WebScrapingAPI的先进功能。







