c#抓取网页数据( 网页抓取是通过自动化手段检索数据的过程-乐题库)
优采云 发布时间: 2022-01-29 01:02c#抓取网页数据(
网页抓取是通过自动化手段检索数据的过程-乐题库)
网页抓取是通过自动化方式检索数据的过程。它在很多场景中都是不可或缺的,例如竞争对手价格监控、房地产上市房源、线索和情绪监控、新闻文章 或财务数据聚合等。
在编写网页抓取代码时,您要做的第一个决定是选择您的编程语言。您可以使用多种语言编写代码,例如 Python、JavaScript、Java、Ruby 或 C#。所有提到的语言都提供了强大的网页抓取功能。
在本文中,我们将探索 C# 并向您展示如何创建一个真正的 C# 公共网络爬虫。请记住,即使我们使用的是 C#,您也可以将此信息改编为 .NET 平台支持的所有语言,包括 VB.NET 和 F#。
01.C#网页抓取工具
在编写任何代码之前,第一步是选择合适的 C# 库或包。这些 C# 库或包将具有下载 HTML 页面、解析它们并从这些页面中提取所需数据的功能。一些最流行的 C# 包如下:
●ScrapySharp
●木偶锋利
●HTML敏捷包
Html Agility Pack 是最受欢迎的 C# 包,仅 Nuget 就有近 5000 万次下载。它的流行有几个原因,其中最重要的是这个 HTML 解析器能够直接或使用浏览器下载网页。这个包容忍格式错误的 HTML 并支持 XPath。此外,它甚至可以解析本地 HTML 文件;因此,我们将在本文中进一步使用这个包。
ScrapySharp 为 C# 编程添加了更*敏*感*词*。这个包支持 CSS 选择器并且可以模拟网络浏览器。虽然 ScrapySharp 被认为是一个强大的 C# 包,但程序员使用它进行维护的概率并不是很高。
Puppeteer Sharp 是著名的 Node.js Puppeteer 项目的 .NET 端口。它使用相同的 Chromium 浏览器来加载页面。此外,此包使用 async-await 风格的代码来支持异步和预操作管理。如果您已经熟悉这个 C# 包并且需要浏览器来呈现页面,那么 Puppeteer Sharp 可能是一个不错的选择。
02.使用C#构建网络爬虫
如前所述,现在我们将演示如何编写将使用 Html Agility Pack 的 C# 公共 Web 抓取代码。我们将使用带有 Visual Studio Code 的 .NET 5 SDK。此代码已在 .NET Core 3 和 .NET 5 上进行了测试,它应该可以在其他版本的 .NET 上运行。
我们将设置一个假设场景:爬取在线书店并采集书名和价格。
在编写 C# 网络爬虫之前,让我们设置开发环境。
03.搭建开发环境
对于 C# 开发环境,请安装 Visual Studio Code。请注意,如果您使用 Visual Studio 和 Visual Studio Code 编写 C# 代码,则需要注意它们是两个完全不同的应用程序。
安装 Visual Studio Code 后,安装 .NET 5.0 或更高版本。您还可以使用 .NET Core 3.1。安装后,打开终端并运行以下命令以验证 .NET CLI 或命令行界面是否正常工作:
dotnet --version
此命令行将输出安装的 .NET 版本号。
04.项目结构及依赖
该代码将成为 .NET 项目的一部分。为简单起见,创建一个控制台应用程序。然后,创建一个文件夹,您将在其中编写 C# 代码。打开终端并导航到该文件夹。输入以下命令:
dotnet new console
此命令的输出应该是控制台应用程序已成功创建。
是时候安装所需的软件包了。使用 C# 抓取公共网页,Html Agility Pack 将是一个不错的选择。你可以为这个项目安装它:
dotnet add package HtmlAgilityPack
再安装一个包,这样我们就可以轻松地将抓取的数据导出到 CSV 文件:
dotnet add package CsvHelper
如果您使用的是 Visual Studio 而不是 Visual Studio Code,请单击文件,选择新建解决方案,然后按控制台应用程序按钮。要安装依赖项,请按照下列步骤操作:
● 选择项目;
● 单击管理项目相关性。这将打开 NuGet 包窗口;
●搜索HtmlAgilityPack并选择它;
● 最后,搜索CsvHelper,选择它,然后单击Add Package。
Visual Studio 中的 Nuget 包管理器
安装这些包后,我们可以继续编写用于抓取在线书店的代码。
05.下载并解析网页数据
任何网页抓取程序的第一步都是下载网页的 HTML。此 HTML 将是一个字符串,您需要将其转换为可以进一步处理的对象,也就是第二步,这部分称为解析。Html Agility Pack 可以从本地文件、HTML 字符串、任何 URL 和浏览器中读取和解析文件。
在我们的例子中,我们需要做的就是从 URL 中获取 HTML。Html Agility Pack 没有使用 .NET 原生函数,而是提供了一个便利类——HtmlWeb。这个类提供了一个Load函数,它接受一个URL并返回一个HtmlDocument类的实例,这也是我们使用的包部分。有了这些信息,我们可以编写一个函数,它接受一个 URL 并返回一个 HtmlDocument 的实例。
打开Program.cs文件,在类中输入这个函数Program:
// Parses the URL and returns HtmlDocument object
static HtmlDocument GetDocument (string url)
{
HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load(url);
return doc;
}
至此,第一步的代码就完成了。下一步是解析文档。
06.解析 HTML:获取图书链接
在这部分代码中,我们将从网页中提取所需的信息。在这个阶段,文档现在是 HtmlDocument 类型的对象。这个类公开了两个函数来选择元素。这两个函数都接受 XPath 输入并返回 HtmlNode 或 HtmlNode采集。
以下是这两个函数的签名:
public HtmlNodeCollection SelectNodes(string xpath);
public HtmlNode SelectSingleNode(string xpath);
让我们先讨论 SelectNodes。
对于这个例子——一个 C# 网络爬虫——我们将从这个页面抓取所有书籍的详细信息。
首先,需要对其进行解析,以便提取所有书籍的链接。在浏览器中打开上述书店页面,右键单击任何书籍链接,然后单击“检查”按钮。开发人员工具将打开。
了解标记后,您要选择的 XPath 应如下所示:
//h3/a
现在可以将此 XPath 传递给 SelectNodes 函数。
HtmlDocument doc = GetDocument(url);
HtmlNodeCollection linkNodes = doc.DocumentNode.SelectNodes("//h3/a");
请注意,SelectNodes 函数是由
由 HtmlDocument 的 DocumentNode 属性调用。
变量 linkNodes 是一个集合。我们可以写一个foreach循环,从每个链接中一一获取href值。我们只需要解决一个小问题——页面上的链接是相对链接。因此,在我们可以抓取这些提取的链接之前,我们需要将它们转换为绝对 URL。
要转换相对链接,我们可以使用 Uri 类。我们使用这个构造函数来获取一个带有绝对 URL 的 Uri 对象。
dotnet --version
一旦我们有了 Uri 对象,我们就可以简单地检查 AbsoluteUri 属性以获取完整的 URL。
我们将所有这些都写在一个函数中以保持代码井井有条。
static List GetBookLinks(string url)
{
var bookLinks = new List();
HtmlDocument doc = GetDocument(url);
HtmlNodeCollection linkNodes = doc.DocumentNode.SelectNodes("//h3/a");
var baseUri = new Uri(url);
foreach (var link in linkNodes)
{
string href = link.Attributes["href"].Value;
bookLinks.Add(new Uri(baseUri, href).AbsoluteUri);
}
return bookLinks;
}
在这个函数中,我们从一个空的 List 对象开始。在 foreach 循环中,我们将所有链接添加到该对象并返回它。
现在,是时候修改 Main() 函数了,以便我们可以测试目前编写的 C# 代码。修改函数如下:
static void Main(string[] args)
{
var bookLinks = GetBookLinks("http://books.toscrape.com/catalogue/category/books/mystery_3/index.html");
Console.WriteLine("Found {0} links", bookLinks.Count);
}
要运行此代码,请打开终端并导航到收录此文件的目录,然后键入以下内容:
dotnet run
输出应如下所示:
Found 20 links
然后我们继续下一部分,我们将处理所有链接以获取图书数据。
07.解析 HTML:获取书籍详情
此时,我们有一个收录书籍 URL 的字符串列表。我们可以简单地编写一个循环,首先使用我们已经编写的函数 GetDocument 获取文档。之后,我们将使用 SelectSingleNode 函数来提取书名和价格。
为了保持数据整洁有序,我们从一个类开始。此类将代表一本书并具有两个属性 - 标题和价格。下面的例子:
然后,在浏览器中为 Title - //h1 打开一个书页。为价格创建 XPath 有点棘手,因为相同的类应用于底部的附加书籍。
XPath 价格
价格的 XPath 将如下所示:
//div[contains(@class,"product_main")]/p[@class="price_color"]
请注意,XPath 收录双引号。我们必须通过在它们前面加上反斜杠来转义这些字符。
现在我们可以使用 SelectSingleNode 函数获取节点,然后使用 InnerText 属性获取元素中收录的文本。我们可以将所有内容放在这样的函数中:
static List GetBookDetails(List urls)
{
var books = new List();
foreach (var url in urls)
{
HtmlDocument document = GetDocument(url);
var titleXPath = "//h1";
var priceXPath = "//div[contains(@class,\"product_main\")]/p[@class=\"price_color\"]";
var book = new Book();
book.Title = document.DocumentNode.SelectSingleNode (priceXPath).InnerText;
book.Price = document.DocumentNode.SelectSingleNode(priceXPath).InnerText;
books.Add(book);
}
return books;
}
此函数将返回 Book 对象的列表。是时候更新 Main() 函数了:
static void Main(string[] args)
{
var bookLinks = GetBookLinks("http://books.toscrape.com/catalogue/category/books/mystery_3/index.html");
Console.WriteLine("Found {0} links", bookLinks.Count);
var books = GetBookDetails(bookLinks);
}
这个网络抓取项目的最后一部分是将数据导出为 CSV。
08.导出数据
如果你没有安装 CsvHelper,你可以通过
dotnet add package CsvHelper
在终端内运行命令来执行此操作。
导出功能非常简单。首先,我们需要创建一个 StreamWriter 并将 CSV 文件名作为参数发送。接下来,我们将使用这个对象来创建一个 CsvWriter。最后,我们可以使用 WriteRecords 函数在一行代码中编写所有书籍。
为了确保所有资源都正确关闭,我们可以使用 using 块。我们还可以将所有内容包装在这样的函数中:
static void exportToCSV(List books)
{
using (var writer = new StreamWriter("./books.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(books);
}
}
最后,我们可以从 Main() 函数中调用这个函数:
static void Main(string[] args)
{
var bookLinks = GetBookLinks("http://books.toscrape.com/catalogue/category/books/mystery_3/index.html");
var books = GetBookDetails(bookLinks);
exportToCSV(books);
}
要运行此代码,请打开终端并运行以下命令:
dotnet run
在几秒钟内,您将创建一个 books.csv 文件。
09.结论
如果你想用 C# 编写一个网络爬虫,你可以使用多个包。在本文中,我们将展示如何使用 Html Agility Pack,这是一个功能强大且易于使用的包。也是一个可以进一步增强的简单示例;例如,您可以尝试将上述逻辑添加到此代码中以处理多个页面。
如果您想了解更多关于如何使用其他编程语言进行网页抓取的信息,您可以查看我们的 Python 网页抓取指南。我们还有另一个
常见问题
问:C# 适合网页抓取吗?
A:与 Python 类似,C# 被广泛用于网页抓取。在决定选择哪种编程语言时,选择您最熟悉的语言至关重要。但是,您将能够在 Python 和 C# 中找到示例网络爬虫。
问:网络抓取合法吗?
答:如果在不违反任何法律的情况下使用代理,它们可能是合法的。但是,在与代理人进行任何活动之前,您应该就您的具体*敏*感*词*获得专业的法律意见。请参阅我们的 文章“网络抓取合法吗?”