c#抓取网页数据( 网页抓取是通过自动化手段检索数据的过程-乐题库)
优采云 发布时间: 2021-10-26 15:09c#抓取网页数据(
网页抓取是通过自动化手段检索数据的过程-乐题库)
网页抓取是通过自动化手段检索数据的过程。在很多场景中都是不可或缺的,比如竞争对手价格监控、房源上市、潜在客户和舆情监控、新闻文章或金融数据聚合。
在编写网络抓取代码时,您必须做出的第一个决定是选择您的编程语言。您可以使用多种语言进行编写,例如 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 选择器,可以模拟 Web 浏览器。虽然 ScrapySharp 被认为是一个强大的 C# 包,但程序员使用它进行维护的概率并不是很高。
Puppeteer Sharp 是著名的 Node.js Puppeteer 项目的 .NET 端口。它使用相同的 Chromium 浏览器来加载页面。此外,该包使用 async-await 风格的代码来支持异步和预操作管理。如果你已经熟悉这个 C# 包并且需要浏览器来渲染页面,那么 Puppeteer Sharp 可能是一个不错的选择。
02. 使用C#搭建网络爬虫
如前所述,现在我们将演示如何编写将使用 Html Agility Pack 的 C# 公共网络爬虫代码。我们将使用 .NET 5 SDK 和 Visual Studio Code。此代码已在 .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,选择它,然后单击添加包。
Visual Studio 中的 Nuget 包管理器
安装完这些包后,我们就可以继续编写爬取网上书店的代码了。
05.下载并解析网页数据
任何网页抓取程序的第一步都是下载网页的 HTML。这个HTML会是一个字符串,你需要把它转换成一个可以进一步处理的对象,这是第二步,这部分叫做解析。Html Agility Pack 可以从本地文件、HTML 字符串、任何 URL 和浏览器读取和解析文件。
在我们的例子中,我们需要做的就是从 URL 中获取 HTML。Html Agility Pack 不使用.NET 原生功能,而是提供了一个方便的类-HtmlWeb。这个类提供了一个Load函数,它可以接受一个URL,并返回一个HtmlDocument类的实例,这也是我们使用Part的包。有了这些信息,我们就可以编写一个接受 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 进行网页抓取的指南。我们还有一个
常见问题
Q:C#适合做网页爬虫吗?
A:与 Python 类似,C# 被广泛用于网络爬虫。在决定选择哪种编程语言时,选择您最熟悉的一种很重要。但是您将能够在 Python 和 C# 中找到示例网络爬虫。
问:网络抓取合法吗?
答:如果在不违反任何法律的情况下使用代理,它们可能是合法的。但是,在与代理人进行任何活动之前,您应该就您的具体*敏*感*词*获得专业的法律建议。请参考我们的文章“网络抓取合法吗?”