7个最佳的C#网页抓取库

有不同的 C# Web Scraping 库来提取数据,包括价格跟踪、潜在客户生成、情绪监控、财务数据聚合等目的。

在选择最佳抓取库时需要考虑不同的指标,在​​本文中,我们将讨论 2023 年使用的 7 个最佳 C# 网络抓取库。此外,我们还将通过示例帮助您了解这些框架的工作原理工作。

什么是最好的 C# Web 抓取库?

我们测试了不同的网络抓取库,2023 年最好使用的库是:

  1. ZenRows.
  2. Puppeteer Sharp.
  3. Selenium.
  4. HTML Agility Pack.
  5. Scrapy Sharp
  6. Iron Web Scraper.
  7. HttpClient.

C# 库是根据使 Web 抓取顺畅的核心功能进行比较的,例如代理配置、动态内容、文档、反机器人绕过、自动解析和基础架构可扩展性。这是一个快速比较:

ZenRows Puppeteer Sharp Selenium HTML Agility Pack Scrapy Sharp Iron web scraper HttpClient
代理配置 自动 手动的 手动的 手动的 手动的 手动的 手动的
动态内容
文档
反机器人绕过
自动解析 HTML
基础架构可扩展性 自动 手动的 手动的 手动的 手动的 手动的 手动的
[/su_table]

让我们继续讨论这些 C# 爬虫库,根据它们附带的功能以及如何使用它们从网页中提取数据。我们将使用ScrapeMe网站作为参考。

scrapeme-webpage-and-source

1. ZenRows 网络爬虫 API

ZenRows API是此列表中最好的 C# 网络抓取库。它是一个 API,用于处理从旋转代理和无头浏览器到验证码的反机器人绕过。此外,它还支持许多流行站点的自动解析(即 HTML 到 JSON 解析),并且可以提取动态内容。

唯一的缺点是 ZenRows 没有任何专有的 C# Nuget 包来将 HTTP 请求发送到它的 Web Scraping API。因此您需要使用额外的包来发送 HTTP 请求。

如何使用 ZenRows 在 C# 中抓取网页

在 ZenRows 上创建一个免费帐户以获取您的 API 密钥。您将进入以下 Request Builder 屏幕:

zenrows-dashboard

添加要呼叫的 URL 后,向其发送 HTTP GET 请求。这会生成可以使用任何 HTML 解析器提取的纯 HTML。

zenrows-generating-api-url

 

如果您用作https://scrapeme.live/shopScrape 的 URL,则 ZenRows API URL 应如下所示:

https://api.zenrows.com/v1/?apikey=API_KEY&url=https%3A%2F%2Fscrapeme.live%2Fshop

请注意, API 密钥是您的个人 ID,不应与任何人共享。

由于 ZenRows 不提供任何可与 C# 程序一起使用的显式 Nuget 包,因此您必须HTTP GET向 API URL 发送请求。ZenRows 将代表您抓取目标 URL 并在响应中返回纯 HTML。

为此,请在 Visual Studio 中创建一个 C# 控制台应用程序并将以下代码添加到该程序的main()函数中:

var url = "https://api.zenrows.com/v1/?apikey=API_KEY&url=https%3A%2F%2Fscrapeme.live%2Fshop"; 
var req = WebRequest.Create(url); 
req.Method = "GET";

此代码将创建一个WebRequest以 ZenRows API URL 作为目标的新对象。然后您可以发送请求并在对象中获取响应HttpResponse

using var resp = req.GetResponse(); 
using var webStream = resp.GetResponseStream();

纯 HTML 响应在对象中获取resp,然后转换为字节流以便于数据读取。现在您在流中有了目标页面的纯 HTML,您可以使用任何 HTML 解析器来解析所需的元素。

让我们使用HTML Agility Pack来提取产品的名称和价格。

安装Agility Pack,ParseHtml()在Program类中编写解析打印产品价格和名称的函数。

private static void ParseHtml(Stream html) 
{ 
    var doc = new HtmlDocument(); 
    doc.Load(html); 
 
    HtmlNodeCollection names = doc.DocumentNode.SelectNodes("//a/h2"); 
    HtmlNodeCollection prices = doc.DocumentNode.SelectNodes("//div/main/ul/li/a/span"); 
 
    for (int i = 0; i < names.Count; i++) 
    { 
        Console.WriteLine("Name: {0}, Price: {1}", names[i].InnerText, prices[i].InnerText); 
    } 
}

ParseHtml()函数创建一个HtmlDocument实例doc并在其中加载传递的字节流。然后它使用该SelectNodes()方法解析所有包含产品名称和价格的元素。

SelectNodes()方法用于XPath从 HTML 文档中提取元素。XPath"//a/h2"选择包含在包含产品名称的<h2>锚标记中的所有元素。<a>

同样,XPath"//div/main/ul/li/a/span"引用所有<span>包含产品价格的元素。这些已解析元素的for循环打印。InnerTexts让我们使用字节流作为参数ParseHTML()从函数中调用方法。main()webStream

ParseHtml(webStream);

您刚刚使用 ZenRows C# 网络抓取库抓取了一个网页……没有被任何反机器人阻止。

zenrows-output

完整代码如下所示:

using HtmlAgilityPack; 
using System; 
using System.IO; 
using System.Net; 
 
namespace ZenRowsDemo 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            var url = "https://api.zenrows.com/v1/?apikey=PUT_YOUR_ZENROWS_API_KEY_HERE&url=https%3A%2F%2Fscrapeme.live%2Fshop"; 
            var request = WebRequest.Create(url); 
            request.Method = "GET"; 
            using var webResponse = request.GetResponse(); 
            using var webStream = webResponse.GetResponseStream(); 
            ParseHtml(webStream); 
        } 
 
        private static void ParseHtml(Stream html) 
        { 
            var doc = new HtmlDocument(); 
            doc.Load(html); 
 
            HtmlNodeCollection names = doc.DocumentNode.SelectNodes("//a/h2"); 
            HtmlNodeCollection prices = doc.DocumentNode.SelectNodes("//div/main/ul/li/a/span"); 
 
            for (int i = 0; i < names.Count; i++) 
            { 
                Console.WriteLine("Name: {0}, Price: {1}", names[i].InnerText, prices[i].InnerText); 
            } 
        } 
    } 
}

2. Puppeteer Sharp

Puppeteer Sharp是一个 C# Web 抓取库,它使用无头浏览器抓取网页。使用 puppeteer sharp 有一些好处,包括能够抓取动态网页、支持无头浏览器以及它可以生成 PDF 和网页截图。

有一些缺点:它需要手动代理集成,它不提供反机器人保护,你必须手动监控你的基础设施可扩展性需求

让我们来看看使用这个库爬取网页是多么容易。

如何使用 Puppeteer Sharp 在 C# 中抓取网页

在 Visual Studio(或您喜欢的 IDE)中创建一个 C# 控制台应用程序,然后PuppeteerSharp通过 NuGet 包管理器安装包,如图所示:

puppeteer-setup

重复相同的过程来安装AngelSharp库。这将方便解析使用包爬取的数据PuppeteerSharp

完成后,让我们继续进行一些 C# 网页抓取。

第一步是在您的Program.cs文件中包含所需的库文件。

using PuppeteerSharp; 
using AngleSharp; 
using AngleSharp.Dom;

完成后,使用 Puppeteer 启动无头 Chrome 实例,并从我们刚刚使用的同一页面获取内容:

using var browserFetcher = new BrowserFetcher(); 
 
await browserFetcher.DownloadAsync(BrowserFetcher.DefaultChromiumRevision); 
 
var browser = await Puppeteer.LaunchAsync(new LaunchOptions 
    { 
        Headless = true, 
        ExecutablePath= @"C:Program FilesGoogleChromeApplicationchrome.exe" 
    }); 
 
var page = await browser.NewPageAsync(); 
await page.GoToAsync("https://scrapeme.live/shop/"); 
 
var content = await page.GetContentAsync();

该代码启动一个无头 Chrome 浏览器实例。该LaunchAsync功能需要 Chrome 浏览器安装目录的路径,该路径可能因您而异,因此请务必提供正确的路径。

GoToAsync()函数将浏览器导航到给定的 URL。该GetContentAsync()方法用于检索当前页面的原始 HTML 内容。

让我们使用AngelSharp解析原始 HTML 内容来提取产品名称和价格。该AngelSharp库使用 LINQ 查询获取要从原始内容中提取的元素的路径。

string jsSelectAllNames = @"Array.from(document.querySelectorAll('h2')).map(a => a.innerText);"; 
 
string jsSelectAllPrices = @"Array.from(document.querySelectorAll('span[class=""price""]')).map(a => a.innerText);"; 
 
var names = await page.EvaluateExpressionAsync<string[]>(jsSelectAllNames); 
 
var prices = await page.EvaluateExpressionAsync<string[]>(jsSelectAllPrices); 
 
for (int i=0; i < names.Length; i++) 
{ 
    Console.WriteLine("Name: {0}, Price: {1}", names[i], prices[i]); 
}

querySelectorAll()函数用于定义所需元素的路径,该map()函数是一个过滤器方法,用于迭代给定元素数组的每个实例以仅保留互文。

EvaluateExpressionAsync()方法计算表达式以提取相关字符串数组中的产品名称和价格。它计算表达式,然后提取并返回匹配结果。

就这样,一个用 Puppeteer C# 爬虫库成功抓取的网页:

puppeteer-scraper-output

完整代码如下所示:

using PuppeteerSharp; 
using System; 
using System.Threading.Tasks; 
using AngleSharp; 
using AngleSharp.Dom; 
using System.Linq; 
using System.Collections.Generic; 
 
namespace PuppeteerDemo 
{ 
    class Program 
    { 
        static async Task Main(string[] args) 
        { 
            using var browserFetcher = new BrowserFetcher(); 
            await browserFetcher.DownloadAsync(BrowserFetcher.DefaultChromiumRevision); 
            var browser = await Puppeteer.LaunchAsync(new LaunchOptions 
            { 
                Headless = true, 
                ExecutablePath= @"C:Program FilesGoogleChromeApplicationchrome.exe" 
            }); 
            var page = await browser.NewPageAsync(); 
            await page.GoToAsync("https://scrapeme.live/shop/"); 
 
            var content = await page.GetContentAsync(); 
 
            List<Products> products = new List<Products>(); 
 
            var jsSelectAllNames = @"Array.from(document.querySelectorAll('h2')).map(a => a.innerText);"; 
 
            var jsSelectAllPrices = @"Array.from(document.querySelectorAll('span[class=""price""]')).map(a => a.innerText);"; 
 
            var names = await page.EvaluateExpressionAsync<string[]>(jsSelectAllNames); 
            var prices = await page.EvaluateExpressionAsync<string[]>(jsSelectAllPrices); 
            for (int i=0; i < names.Length && i < prices.Length; i++) 
            { 
                Products p = new Products(); 
                p.Name = names[i]; 
                p.Price = prices[i]; 
                products.Add(p); 
            } 
            foreach(var p in products) 
            { 
                Console.WriteLine("Name: {0}, Price: {1}", p.Name, p.Price); 
            } 
        } 
    } 
    class Products 
    { 
        private string name; 
        private string price; 
 
        public string Name { get => name; set => name = value; } 
        public string Price { get => price; set => price = value; } 
    } 
}

3.Selenium网络驱动程序

Selenium是用于抓取大量数据(如照片、链接和文本)的最常用工具之一。它是抓取动态网页的理想选择,因为它能够处理使用 JavaScript 生成的动态内容。

Selenium C# 抓取库的缺点是它需要手动代理集成和反机器人机制。

如何使用 Selenium 在 C# 中抓取网页

使用 Selenium 构建网络爬虫需要两个外部包:Selenium Web DriverSelenium Webdriver.ChromeDriver. 您可以使用 NuGet 包管理器安装这些包:

selenium-setup

安装完这些后,通过指定其多个选项(例如浏览器路径、GPU 支持等)启动无头 Chrome 驱动程序。

string fullUrl = "https://scrapeme.live/shop/"; 
var options = new ChromeOptions(){ 
    BinaryLocation = "C:\Program Files\Google\Chrome\Application\chrome.exe" 
}; 
 
options.AddArguments(new List<string>() { "headless", "disable-gpu" }); 
 
var browser = new ChromeDriver(options); 
browser.Navigate().GoToUrl(fullUrl);

在浏览器导航到所需的 URL 后,使用该FindElements函数提取元素。

var names = browser.FindElements(By.TagName("h2")); 
var prices = browser.FindElements(By.CssSelector("span.price")); 
 
for (int i = 0; i < names.Count && i < prices.Count; i++) 
{ 
    Console.WriteLine("Name: {0}, Price: {1}", names[i], prices[i]); 
}

您的输出如下所示:

selenium-scraper-output

如果你迷路了,这里是使用的完整代码:

using OpenQA.Selenium.Chrome; 
using System; 
using OpenQA.Selenium; 
using System.Collections.Generic; 
using System.Threading.Tasks; 
 
namespace SeleniumDemo { 
    class Program { 
        static void Main(string[] args) { 
            string fullUrl = "https://scrapeme.live/shop/"; 
            List<string> programmerLinks = new List<string>(); 
 
            var options = new ChromeOptions() { 
                BinaryLocation = "C:\Program Files\Google\Chrome\Application\chrome.exe" 
            }; 
 
            options.AddArguments(new List<string>() { 
                "headless", 
                "disable-gpu" 
            }); 
 
            var browser = new ChromeDriver(options); 
            List<Products> products = new List<Products>(); 
            browser.Navigate().GoToUrl(fullUrl); 
 
            var names = browser.FindElements(By.TagName("h2")); 
            var prices = browser.FindElements(By.CssSelector("span.price")); 
            for (int i = 0; i < names.Count && i < prices.Count; i++) { 
                Products p = new Products(); 
                p.Name = names[i].GetAttribute("innerText"); 
                p.Price = prices[i].GetAttribute("innerText"); 
                products.Add(p); 
            } 
            foreach(var p in products) { 
                Console.WriteLine("Name: {0}, Price: {1}", p.Name, p.Price); 
            } 
        } 
    } 
    class Products { 
        string name; 
        string price; 
 
        public string Name { 
            get => name; 
            set => name = value; 
        } 
        public string Price { 
            get => price; 
            set => price = value; 
        } 
    } 
}

4. HTML Agility Pack

HTML Agility Pack是下载次数最多的 C# DOM 抓取程序库,因为它能够直接或通过浏览器下载网页。HTML Agility 包可以处理损坏的 HTML 并支持 XPath,它还可以扫描本地 HTML 文件。

也就是说,这个 C# 网络爬虫库不支持无头抓取,它需要外部代理服务来绕过反机器人。

如何使用 HTML Agility Pack 在 C# 中抓取网页

创建 C# 控制台应用程序并从“工具”菜单中打开 NuGet 包管理器。在浏览选项卡下的搜索栏中键入HTML Agility Pack,选择合适版本的 HtmlAgilityPack,然后单击安装。

installing-agility-pack

一旦我们安装了工具,让我们去提取一些数据。第一步是在您的Program.cs文件中包含所需的库文件:

using HtmlAgilityPack;

然后创建一个辅助方法来GetDocument()加载 URL 的 HTML 并返回 HTML 内容:

static HtmlDocument GetDocument(string url) 
{ 
    HtmlWeb web = new HtmlWeb(); 
    HtmlDocument doc = web.Load(url); 
    return doc; 
}

您可以使用它GetDocument()来检索任何目标页面的 HTML 内容。最后一步是编写main()驱动程序代码,如下所示:

var doc = GetDocument("https://scrapeme.live/shop/"); 
 
HtmlNodeCollection names = doc.DocumentNode.SelectNodes("//a/h2"); 
HtmlNodeCollection prices = doc.DocumentNode.SelectNodes("//div/main/ul/li/a/span"); 
 
for (int i = 0; i < names.Count(); i++){ 
    Console.WriteLine("Name: {0}, Price: {1}", names[i].InnerText, prices[i].InnerText); 
}

GetDocument()函数检索给定目标的 HTML 内容。该SelectNodes()函数使用相关的XPath选择器来解析目标网页上的产品名称和价格。该for循环打印所有InnerText已解析的元素。

就是这样!ScrapeMe 刚刚使用 HTML Agility Pack C# 网络爬虫库进行了爬虫。

agility-scraper-output

完整代码如下所示:

using HAP_Demo; 
using HtmlAgilityPack; 
using System; 
using System.Collections.Generic; 
using System.Linq; 
 
namespace ConsoleApp2 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            var doc = GetDocument("https://scrapeme.live/shop/"); 
 
            HtmlNodeCollection names = doc.DocumentNode.SelectNodes("//a/h2"); 
            HtmlNodeCollection prices = doc.DocumentNode.SelectNodes("//div/main/ul/li/a/span"); 
            List<Products> products = new List<Products>(); 
 
            for (int i = 0; i < names.Count && i < prices.Count; i++) 
            { 
                Products p = new Products(); 
                p.Name= names[i].InnerText; 
                p.Price = prices[i].InnerText; 
                products.Add(p); 
            } 
            foreach (var p in products) 
            { 
                Console.WriteLine("Name: {0} , Price: {1}", p.Name, p.Price); 
            } 
        } 
        static HtmlDocument GetDocument(string url) 
        { 
            HtmlWeb web = new HtmlWeb(); 
            HtmlDocument doc = web.Load(url); 
            return doc; 
        } 
    } 
 
    class Products 
    { 
        private string name; 
        private string price; 
 
        public string Name { get => name; set => name = value; } 
        public string Price { get => price; set => price = value; } 
    } 
}

5. Scrapy Sharp

Scrapy Sharp是一个开源的 C# 网络爬虫库,它将HTMLAgilityPack扩展与可以模拟网络浏览器(例如 jQuery)的网络客户端相结合。

它显着减少了通常与抓取网页相关的设置工作,并且它与 HTMLAgilitypack 的结合使您可以轻松访问检索到的 HTML 内容。Scrapy Sharp 可以模拟网络浏览器,因此它可以处理 cookie 跟踪、重定向和其他高级操作。

使用 Scrapy Sharp C# 抓取库的缺点是需要代理和反机器人,并且不支持自动解析抓取的内容。

如何使用 Scrapy Sharp 在 C# 中抓取网页

ScrapySharp创建一个 C# 控制台应用程序项目并通过 NuGet 包管理器安装最新的包。从您的控制台应用程序打开Program.cs文件并包含以下必需的库。

using HtmlAgilityPack; 
using ScrapySharp.Network; 
using System; 
using System.Linq;

接下来,在类中创建一个static ScrapingBrowser对象Program。您可以使用此对象的功能(例如mybrowser)来导航和抓取目标 URL。

static ScrapingBrowser mybrowser = new ScrapingBrowser();

创建一个辅助方法来检索和返回给定目标 URL 的 HTML 内容。

static HtmlNode GetHtml(string url) 
{ 
    WebPage webpage = mybrowser.NavigateToPage(new Uri(url)); 
    return webpage.Html; 
}

helperGetHtml方法将目标 URL 作为参数并将其发送到对象NavigateToPage()的方法mybrowser,返回网页的 HTML。

让我们再创建一个辅助方法来提取和打印产品名称和价格:

static void ScrapeNamesAndPrices(string url) 
{ 
    var html = GetHtml(url); 
 
    var nameNodes = html.OwnerDocument.DocumentNode.SelectNodes("//a/h2"); 
    var priceNodes = html.OwnerDocument.DocumentNode.SelectNodes("//div/main/ul/li/a/span"); 
 
    foreach (var (n, p) in nameNodes.Zip(priceNodes)) 
    { 
        Console.WriteLine("Name: {0} , Price: {1}", n.InnerText, p.InnerText); 
    } 
}

此代码段使用 方法GetHtml()检索 URL 的 HTML 并使用SelectNodes()函数解析它。该SelectNodes()函数使用产品名称和价格的 XPath,并返回具有相同 XPath 的所有元素。

foreach循环获取和集合InnerText中的每个元素并将它们打印在控制台上。最后一点,添加驱动程序代码以使一切井井有条。nameNodepriceNode

static void Main(string[] args) 
{ 
    ScrapeNamesAndPrices("https://scrapeme.live/shop/"); 
}

scrapysharp-output

这是最终代码的样子:

using HtmlAgilityPack; 
using ScrapySharp.Network; 
using System; 
using System.Linq; 
namespace ScrapyDemo 
{ 
    class Program 
    { 
        static ScrapingBrowser mybrowser = new ScrapingBrowser(); 
        static void Main(string[] args) 
        { 
            ScrapeNamesAndPrices("https://scrapeme.live/shop/"); 
        } 
        static HtmlNode GetHtml(string url) 
        { 
            WebPage webpage = mybrowser.NavigateToPage(new Uri(url)); 
            return webpage.Html; 
        } 
        static void ScrapeNamesAndPrices(string url) 
        { 
            var html = GetHtml(url); 
            var nameNodes = html.OwnerDocument.DocumentNode.SelectNodes("//a/h2"); 
            var priceNodes = html.OwnerDocument.DocumentNode.SelectNodes("//div/main/ul/li/a/span"); 
 
            foreach (var (n, p) in nameNodes.Zip(priceNodes)) 
            { 
                Console.WriteLine("Name: {0} , Price: {1}", n.InnerText, p.InnerText); 
            } 
        } 
    } 
}

6. Iron web scraper

IronWebscraper是一个 .Net Core C# 网络抓取库用于从互联网资源中提取和解析数据。它能够控制允许和不允许的对象、站点、媒体和其他元素。

其他功能包括其管理众多身份和网络缓存的能力。

使用这个 C# 网络爬虫库的主要缺点是:

  • 它不支持抓取动态内容。
  • 需要手动代理集成。

如何使用 Iron Web Scraper 在 C# 中抓取网页

为这个 C# 爬虫库设置开发环境非常简单。只需将IronWebScraper包安装到您的 C# 控制台项目,您就可以开始了!

ironwebscraper-setup

WebScraper中的类有IronWebScraper两个抽象方法:InitParse。该Init方法初始化 Web 请求并获取响应。然后将此响应传递给Parse函数以从 HTML 内容中提取所需的元素。

要创建您的 Iron 网络抓取工具,您必须继承该类WebScraper并覆盖这两个抽象方法。如果您IronScraperDemo在文件中有作为主要的抓取器类Program.csWebScraper请像这样实现该类:

class IronScraperDemo : WebScraper 
{ 
    public override void Init() 
    { 
        License.LicenseKey = "ENTER YOUR LICENSE KEY HERE"; 
        this.LoggingLevel = WebScraper.LogLevel.All; 
        this.Request("https://scrapeme.live/shop/", Parse); 
    } 
 
    public override void Parse(Response response) 
    { 
        var names = response.Css("h2"); 
        var prices = response.Css("span.price"); 
        for(int i=0; i<names.Length;i++) 
        { 
            Console.WriteLine("Name: {0}, Price: {1}", names[i].InnerText, prices[i].InnerText); 
        } 
    } 
}

Init方法要求您添加一个许可证密钥,您可以通过在他们的网站上创建一个帐户来获得它。该函数在请求目标 URL 后Init进一步调用接收到的响应的方法。Parse

在我们的例子中,该Parse方法使用 CSS 选择器从响应中提取产品名称和价格,并将它们打印在输出控制台上。

您的 Iron Web Scraper 已准备就绪。只需添加以下驱动程序代码即可创建爬虫对象并调用其Start()方法。

static void Main(string[] args) 
{ 
    IronScraperDemo ironScraper = new IronScraperDemo(); 
    ironScraper.Start(); 
}

使用 Iron Web Scraper 抓取目标网页,您的输出应如下所示:

ironwebscraper-output

Program.cs下面是这个例子的完整代码:

using IronWebScraper; 
using System; 
using System.Collections.Generic; 
 
namespace IronScrapDemo 
{ 
    class IronScraperDemo : WebScraper 
    { 
        List<Products> products = new List<Products>(); 
        static void Main(string[] args) 
        { 
            IronScraperDemo ironScraper = new IronScraperDemo(); 
            ironScraper.Start(); 
        } 
        public override void Init() 
        { 
            License.LicenseKey = "ENTER YOUR LICENSE KEY HERE"; 
            this.LoggingLevel = WebScraper.LogLevel.All; // All Events Are Logged 
            this.Request("https://scrapeme.live/shop/", Parse); 
        } 
 
        public override void Parse(Response response) 
        { 
            var names = response.Css("h2"); 
            var prices = response.Css("span.price"); 
            for (int i=0; i < names.Length; i++) 
            { 
                Products p = new Products(); 
                p.Name = names[i].InnerText; 
                p.Price = prices[i].InnerText; 
                products.Add(p); 
            } 
            foreach(var p in products) 
            { 
                Console.WriteLine("Name: {0}, Price: {1}", p.Name, p.Price); 
            } 
        } 
    } 
    class Products 
    { 
        public String Name 
        { 
            get; 
            set; 
        } 
        public String Price 
        { 
            get; 
            set; 
        } 
    } 
}

备注:您仍然需要按照本节中的说明设置开发环境。

7.HttpClient

HttpClient是一个 C# HTML 抓取程序库,它提供异步功能以仅从目标 URL 中提取原始 HTML 内容。但是,您仍然需要使用 HTML 解析工具来提取所需的数据。

如何使用 HttpClient 在 C# 中抓取网页

HttpClient 是原始 .NET 类,不需要任何外部程序集,但您必须通过包管理器将 HTML Agility Pack 安装为外部依赖项。

首先,在 C# 控制台应用程序下的“Program.cs”文件中包含以下程序集:

using System; 
using System.Threading.Tasks; 
using System.Net.Http; 
using HtmlAgilityPack;

该类System.Threading.Tasks有助于处理异步函数。需要导入System.Net.Http生成 HTTP 请求,并HtmlAgilityPack用于解析检索到的 HTML 内容。

在类中添加一个GetHtmlContent()方法Program,如下所示:

private static Task<string> GetHtmlContent() 
{ 
    var hclient = new HttpClient(); 
    return hclient.GetStringAsync("https://scrapeme.live/shop"); 
}

您可以将此字符串响应传递给ParseHtml()提取和显示所需数据的方法。

 private static void ParseHtml(string html) 
{ 
    var doc = new HtmlDocument(); 
    doc.LoadHtml(html); 
 
    HtmlNodeCollection names = doc.DocumentNode.SelectNodes("//a/h2"); 
 
    HtmlNodeCollection prices = doc.DocumentNode.SelectNodes("//div/main/ul/li/a/span"); 
 
    for (int i = 0; i < names.Count; i++){ 
        Console.WriteLine("Name: {0}, Price: {1}", names[i].InnerText, prices[i].InnerText); 
    } 
}

上面的代码ParseHTML将 HTML 字符串作为输入,然后使用SelectNodes()方法对其进行解析,并在输出控制台上显示名称和价格。这里的SelectNodes()函数起着关键的解析作用。它根据给定的 XPath 选择器仅从 HTML 字符串中提取相关元素。

总结一下,让我们看一下按顺序执行所有操作的驱动程序代码:

static async Task Main(string[] args) 
{ 
    var html = await GetHtmlContent(); 
    ParseHtml(html); 
}

请注意,该Main()函数现在是一种async方法。原因是每次awaitable调用只能包含在一个async方法中;因此,Main()函数必须是异步的。

与本文讨论的其他 C# 网络抓取库一样,您的输出将是:

httpclient-scraper-output

这是连接在一起的所有代码块的样子

using System; 
using System.Threading.Tasks; 
using System.Collections.Generic; 
using System.Net.Http; 
using System.Threading.Tasks; 
using HtmlAgilityPack; 
namespace ConsoleApp1 
{ 
    class Program 
    { 
        static async Task Main(string[] args) 
        { 
            var html = await GetHtmlContent(); 
            List<Products> products = ParseHtml(html); 
            foreach (var p in products) 
            { 
                Console.WriteLine("Name: {0} , Price: {1}", p.Name, p.Price); 
            } 
        } 
 
        private static Task<string> GetHtmlContent() 
        { 
            var hclient = new HttpClient(); 
            return hclient.GetStringAsync("https://scrapeme.live/shop"); 
        } 
 
        private static List<Products> ParseHtml(string html) 
        { 
            var doc = new HtmlDocument(); 
            doc.LoadHtml(html); 
 
            HtmlNodeCollection names = doc.DocumentNode.SelectNodes("//a/h2"); 
            HtmlNodeCollection prices = doc.DocumentNode.SelectNodes("//div/main/ul/li/a/span"); 
 
            List<Products> products = new List<Products>(); 
 
            for (int i = 0; i < names.Count && i < prices.Count; i++) 
            { 
                Products p = new Products(); 
                p.Name = names[i].InnerText; 
                p.Price = prices[i].InnerText; 
                products.Add(p); 
            } 
 
            return products; 
        } 
    } 
    class Products 
    { 
        public String Name 
        { 
            get; 
            set; 
        } 
        public String Price 
        { 
            get; 
            set; 
        } 
    } 
}

结论

有不同的库能够从网页中提取数据,但我们已经进行了深度测试,并展示了 2023 年使用的 7 个最佳 C# 网络抓取库。如图所示,它们是:

  1. ZenRows.
  2. Puppeteer Sharp.
  3. Selenium.
  4. HTML Agility Pack.
  5. Scrapy Sharp
  6. Iron Web Scraper.
  7. HttpClient.

爬虫之间的一个共同挑战是他们无法在不触发反机器人的情况下抓取网页。

常见问题

什么是最好的 C# 网络抓取库?

ZenRows API是 C# 中网页抓取的最佳选择。与其他 C# 网络抓取库不同,它不需要手动集成代理或设置反机器人逻辑。它还支持使用 AutoParse 功能抓取动态内容。

HTML Agility Pack 是最受欢迎的库,下载量约为 8300 万次。它受欢迎的主要原因是它的 HTML 解析器,它可以直接或通过浏览器下载网页。

什么是好的 C# 网络抓取库?

一个好的抓取库提供了有效的机制来抓取和解析目标内容,避免任何阻塞(包括反机器人/验证码)或泄露您的 IP。此外,它应该支持抓取动态内容,并且应该有全面的文档和积极的社区支持。考虑到这些指标,ZenRows、Puppeteer Sharp 和 Selenium 是使用 C# 抓取网页的不错选择。

类似文章