返回博客

C#网页抓取指南: 从零到生产代码(2025版)

手动从网站复制数据?那是实习生该做的,但你没有实习生。好消息: C#可以自动化繁琐的工作。虽然Python主导了网页抓取的话题,但C#已经成长为一个真正的竞争者,拥有强大的库、类型安全性和在生产中真正重要的性能。让我们深入了解它。

Zilvinas Tamulis

12月 12日, 2025年

15 分钟阅读

什么是C#网页抓取?

网页抓取是从网站自动提取数据,可以把它想象成批量下载公开可见但令人烦恼地困在HTML中的信息。开发人员将其用于价格监控、潜在客户生成、市场研究、竞争对手分析,以及基本上任何手动复制粘贴会让你发疯的场景。

C#并不总是抓取的明显选择。Python凭借Beautiful Soup和Scrapy占据了这个领域。但.NET 8改变了游戏规则,提供了跨平台支持、改进的性能和成熟的生态系统。出现了各种优雅处理静态HTML解析的库,而Selenium和PuppeteerSharp则处理JavaScript密集型网站。结果如何?C#现在提供类型安全、异步功能和IDE工具,使抓取感觉不像是将脚本粘在一起,而更像是真正的工程。

在本指南中,您将从头开始构建一个功能齐全的C#抓取器。我们要讨论环境设置、依赖管理、从静态和动态页面提取数据,以及将所有内容导出到干净的CSV文件。

先决条件: 您应该了解基本的C#语法并理解面向对象编程的概念。如果您可以编写一个类并理解方法的作用,那就没问题。这适用于Windows、Linux和macOS,.NET不歧视。

设置您的C#网页抓取环境

在抓取任何内容之前,您需要三样东西: .NET SDK(实际的编译器和运行时)、Visual Studio Code(您的IDE)和NuGet包管理器(安装库)。

以下是它们如何协同工作的: .NET SDK将您的C#代码编译成可执行程序并提供dotnet CLI工具。Visual Studio Code只是一个具有超能力的文本编辑器,语法高亮、调试、IntelliSense,但它实际上不编译任何东西。从技术上讲,您可以在记事本中编写C#并使用SDK编译它,但为什么要折磨自己呢?最后,NuGet允许您轻松地将第三方库添加到您的工作中,这样您就不必从头开始发明HTTP请求。

专业提示: 使用VS Code的集成终端。它将所有内容保持在一个窗口中,您不会失去对哪个终端属于哪个项目的跟踪。

安装.NET SDK和Visual Studio Code

让我们完成设置,这样您就可以开始编写代码了。

步骤1. 下载.NET SDK

前往Microsoft的.NET下载页面并获取最新的.NET SDK(8.0或更新版本)。运行安装程序,点击几次下一步,让它完成。这也会安装NuGet,所以您不必担心单独的安装,可以立即使用它。

步骤2. 下载Visual Studio Code

为您的操作系统获取Visual Studio Code。安装并启动应用程序。打开后,按Ctrl+Shift+X(macOS上为Cmd+Shift+X)打开扩展面板。

步骤3. 安装C#扩展

搜索并安装这些:

  • C# Dev Kit(Microsoft的官方扩展包)
  • C# Extensions(确保它不是已弃用的版本)

这些为您提供IntelliSense、调试和语法高亮。它们是高效编写和测试代码的必需品。

步骤4. 验证安装

打开终端(或VS Code的集成终端)并运行:

dotnet --version

一键获取完整项目代码

您应该看到类似"10.0.100"的内容。如果出现错误,说明SDK不在系统PATH中,请参阅下面的解决方案。

常见问题

"dotnet"不是内部或外部命令

安装程序没有将.NET添加到您的PATH。首先重新启动终端,看看是否能解决问题。如果这不起作用:

  • Windows: 开始菜单中搜索环境变量,编辑PATH,并添加*C:\Program Files\dotnet*
  • macOS/Linux: export PATH=" PATH : PATH: PATH:HOME/.dotnet添加到您的.bashrc.zshrc文件(位于您的主目录中。可以使用"cd /"命令找到),然后运行source ~/.bashrc

VS Code找不到SDK

打开VS Code设置(Ctrl+,/Cmd+,),搜索"dotnet path",并手动将其指向您的SDK安装目录。通常,在Windows上是C:\Program Files\dotnet\dotnet.exe,在macOS上是/usr/local/share/dotnet/dotnet

使用dotnet new创建控制台项目

让我们开始构建项目。您首先将创建一个控制台应用程序,这是运行小型自动化任务和执行测试的最简单方法。

打开您的终端(或VS Code的集成终端)并运行这些命令:

dotnet new console -n WebScraper
cd WebScraper

这会创建一个名为"WebScraper"的新文件夹,其中包含您开始编码所需的一切。-n标志命名您的项目,您可以随意命名它,但要确保它不是像"test-script-final-final-version2"这样的东西,这样您就会在六个月后记住它的作用。

创建后,您的项目结构将如下所示:

WebScraper/
├── Program.cs # Your main entry point
├── WebScraper.csproj # Project configuration file
├── obj/ # Intermediate build files (ignore this)
└── bin/ # Compiled output goes here

选择正确的C#网页抓取库

C#没有单一的"官方"抓取库,因为不同的网站需要不同的方法。一些网站提供加载时已准备好解析的纯HTML。其他网站在初始页面加载后使用JavaScript框架来呈现内容。您需要适合工作的正确工具,否则您最终会抓取空div,想知道为什么什么都不起作用。

静态与动态内容: 有什么区别?

静态内容是在到达浏览器之前在服务器上完全呈现的HTML。当您查看页面源代码(Ctrl+U/Cmd+U)时,您会看到想要抓取的实际数据。新闻网站、博客和文档页面通常属于这一类。

动态内容是在页面加载后由JavaScript生成的。初始HTML通常是一个带有空容器的骨架,JavaScript使用AJAX请求或客户端呈现填充它们。单页应用程序(React、Vue、Angular)和现代电子商务网站因此而臭名昭著。如果您查看源代码但看不到您要找的数据,那就是动态的。

HtmlAgilityPack vs Selenium vs PuppeteerSharp

以下是您可以选择的领先C#网页抓取库:

最适合

优点

缺点

HtmlAgilityPack

静态HTML解析

轻量、快速、简单的API、XPath支持

无法处理JavaScript呈现的内容

Selenium

带有JavaScript的动态页面

完整的浏览器自动化、广泛使用、稳定

慢、资源密集、需要WebDriver管理

PuppeteerSharp

无头Chrome自动化

现代API、适合SPA、比Selenium快

学习曲线陡峭、生态系统不太成熟

当数据在"查看源代码"中可见时使用HtmlAgilityPack。它是最快的选项,不会启动浏览器。非常适合抓取博客、具有服务器端呈现的产品列表或2015年之前构建的任何网站。如果您来自Python的Beautiful Soup,这就是您的等价物。

当内容在页面呈现后加载时使用Selenium,想想无限滚动、延迟加载的图像或通过API调用获取的数据。它经过实战考验,文档广泛。是的,它比解析原始HTML慢,但它实际上在现代网站上有效。

如果您想要Selenium的功能和更清晰的API,请使用PuppeteerSharp。它是Google的Puppeteer库的C#移植版本。如果您已经熟悉无头Chrome工作流程或需要高级浏览器控制(如请求拦截),这是一个不错的选择。

在本指南的以下部分中,您将看到如何使用HtmlAgilityPack处理静态内容和Selenium处理动态内容。这并不意味着它们是最好的选择,因为存在许多其他库,如ScrapySharp,它们根据您的特定需求提供完全不同的功能。

通过NuGet安装HtmlAgilityPack

要安装HtmlAgilityPack,从您的项目目录运行:

dotnet add package HtmlAgilityPack

您将看到确认已添加包的输出。该命令下载HtmlAgilityPack并自动更新您的项目文件。

要验证安装,在VS Code中打开WebScraper.csproj文件。您应该看到一个新的部分,如下所示:

<ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.61" />
</ItemGroup>

添加CsvHelper用于CSV导出

如果您无法将抓取的数据导出到某个有用的地方,那么抓取数据就毫无意义。您可以手动编写CSV格式化逻辑,连接字符串、转义逗号、处理换行符,但为什么要浪费时间重新发明轮子呢?CsvHelper的存在就是为了解决这个问题。

CsvHelper是C#中CSV操作的事实标准。它自动处理编码、特定于文化的格式和边缘情况(如包含逗号或引号的字段)。您定义一个类,传递一个对象列表,它就会生成格式正确的CSV。没有意外,没有凌晨2点的bug,因为某人的公司名称中有逗号。

但您可能会问,为什么选择CSV?因为它是通用数据格式。Excel打开它,Google表格导入它,Pandas读取它,数据库摄取它。对于您的第一个抓取项目,CSV是阻力最小的路径。您不必处理JSON模式验证、数据库连接或API速率限制,只需任何人都能理解的行和列。

一旦您的抓取器工作,您总是可以将CSV换成JSON、SQL或您的管道需要的任何东西。但从简单开始。

在您的项目目录中运行:

dotnet add package CsvHelper

就是这样。CsvHelper现在与HtmlAgilityPack一起在您的项目中了。如果您想查看其他NuGet包或探索不同版本,请浏览官方NuGet画廊。

现在您已经有了抓取和导出的工具。是时候编写实际代码了。

使用HtmlAgilityPack构建静态网页抓取器

对于这个示例项目,让我们从quotes.toscrape.com抓取引用,这是一个专为此目的而设计的练习网站。该网站显示带有作者和标签的引用。HTML是服务器呈现的,这意味着所有内容在加载时已经在页面源代码中。非常适合HtmlAgilityPack。

使用HtmlWeb.Load()加载HTML

HtmlAgilityPack提供两种获取网页的方法: 同步和异步。对于大多数抓取任务,尤其是当您刚开始学习时,同步更简单。

同步加载会阻止您的程序,直到页面完全加载。打开Program.cs并编写以下代码:

using HtmlAgilityPack;
var web = new HtmlWeb();
var doc = web.Load("https://quotes.toscrape.com/");
Console.WriteLine("Page loaded successfully!");
Console.WriteLine($"Title: {doc.DocumentNode.SelectSingleNode("//title").InnerText}");

保存文件并在终端中使用此命令运行它:

dotnet run

您将在终端中看到打印的页面标题。这是一项简单的任务,但它确认库可以工作,并为进一步的抓取任务奠定了基础。

使用SelectNodes()和SelectSingleNode()的XPath

XPath是用于导航HTML/XML结构的查询语言。它就像文档的SQL,一开始有点神秘,但一旦您理解了语法,就会非常强大。

基本XPath模式:

// Select ALL matching elements
var quoteNodes = doc.DocumentNode.SelectNodes("//div[@class='quote']");
// Select the FIRST matching element
var firstQuote = doc.DocumentNode.SelectSingleNode("//div[@class='quote']");

"//“告诉应用程序在文档中的任何位置搜索。[@class=‘quote’]过滤具有该特定类属性的元素。要找到它们,您应该知道如何在浏览器中"检查元素”。

让我们提取实际数据:

using HtmlAgilityPack;
var web = new HtmlWeb();
var doc = web.Load("https://quotes.toscrape.com/");
// Select all quote containers
var quoteNodes = doc.DocumentNode.SelectNodes("//div[@class='quote']");
foreach (var quoteNode in quoteNodes)
{
// Extract nested elements using relative XPath (starts with .)
var text = quoteNode.SelectSingleNode(".//span[@class='text']").InnerText;
var author = quoteNode.SelectSingleNode(".//small[@class='author']").InnerText;
Console.WriteLine($"Quote: {text}");
Console.WriteLine($"Author: {author}");
Console.WriteLine("---");
}

脚本前往网站,通过定义的XPath找到所需的信息,并打印引用和作者名称。

使用HtmlEntity.DeEntitize()清理HTML实体

如果您运行了上面的代码,您可能注意到终端中的文本看起来有点奇怪:

引用: "I have not failed. I&#39;ve just found 10,000 ways that won&#39;t work."

那些"'I&#39"是HTML实体,特殊字符的编码表示。浏览器会自动解码它们,但当您提取InnerText时,您会得到原始编码版本。

要解决此问题,您必须在输出之前解码它们:

using HtmlAgilityPack;
var web = new HtmlWeb();
var doc = web.Load("https://quotes.toscrape.com/");
var quoteNodes = doc.DocumentNode.SelectNodes("//div[@class='quote']");
foreach (var quoteNode in quoteNodes)
{
var text = quoteNode.SelectSingleNode(".//span[@class='text']").InnerText;
var author = quoteNode.SelectSingleNode(".//small[@class='author']").InnerText;
// Decode HTML entities to readable text
text = HtmlEntity.DeEntitize(text);
Console.WriteLine($"Quote: {text}");
Console.WriteLine($"Author: {author}");
Console.WriteLine("---");
}

干净多了。在写入CSV或JSON之前,始终运行DeEntitize(),您的数据分析师会感谢您。

现在让我们解决更复杂的问题: JavaScript呈现的页面。

使用Selenium抓取JavaScript呈现的页面

HtmlAgilityPack工作得很完美,直到您遇到一个"查看源代码"只显示空div容器的网站。

这就是Selenium拯救您的地方。它不仅仅是一个抓取和解析库,它是一个浏览器自动化框架。Selenium启动一个实际的Chrome(或Firefox)实例,导航到页面,等待JavaScript执行,然后让您从完全呈现的DOM中提取数据。

Selenium如何工作: WebDriver架构

Selenium使用WebDriver协议来控制浏览器。把它想象成一个遥控器:

  1. 您的C#代码向WebDriver发送命令(例如"导航到此URL",“单击此按钮”)
  2. WebDriver将这些命令转换为特定于浏览器的指令
  3. Chrome(通过ChromeDriver)执行指令并发送回结果
  4. 您的代码接收数据并继续

这种往返使Selenium比纯HTTP请求慢,因为您正在驱动一个完整的浏览器。尽管如此,当页面严重依赖JavaScript生成内容时,真正的浏览器引擎通常是唯一实用的选择。

负责任的自动化

自动化浏览器可以比人类更快地发送请求,用1000个并发Selenium实例猛击服务器会让您的IP立即被禁止。在请求之间添加延迟(Thread.Sleep()或更好的方法,使用指数退避)。尊重robots.txt。如果网站明确阻止自动化,不要试图规避它,使用像Decodo网页抓取API这样正确处理速率限制和代理的服务。

另外,如果您正在尝试AI辅助的抓取工作流程,请查看我们的ChatGPT网页抓取指南。

现在让我们为quotes.toscrape.com/js构建一个抓取器,这是您之前抓取的网站的JavaScript呈现版本。

安装Selenium.WebDriver和ChromeDriver

您需要两个包: Selenium库本身和控制Chrome的ChromeDriver二进制文件。在您的项目目录中运行这些命令:

dotnet add package Selenium.WebDriver
dotnet add package Selenium.WebDriver.ChromeDriver

在无头模式下启动Chrome

无头模式在没有可见窗口的情况下运行Chrome。没有GUI意味着更少的内存使用和更快的执行。这是在Program.cs中编写的基本脚本:

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
// Configure Chrome options
var options = new ChromeOptions();
options.AddArgument("--headless"); // Run without GUI
options.AddArgument("--disable-gpu"); // Disable GPU acceleration (recommended for headless)
options.AddArgument("--no-sandbox"); // Bypass OS security model (needed in some environments)
// Launch Chrome with these options
var driver = new ChromeDriver(options);
try
{
driver.Navigate().GoToUrl("https://quotes.toscrape.com/js/");
Console.WriteLine($"Page title: {driver.Title}");
}
finally
{
driver.Quit(); // ALWAYS close the browser
}

使用以下命令运行:

dotnet run

您不会看到浏览器窗口打开,但您应该在终端中看到:

页面标题: Quotes to Scrape

如果您在运行脚本后遇到找不到驱动程序的问题,请检查chromedriver.exe(或chromedriver)是否存在于输出文件夹中。某些杀毒软件会标记它,如果需要请添加例外。

为什么无头很重要:

  • 速度. 没有您永远看不到的UI元素的渲染开销
  • 服务器环境. 许多CI/CD服务器没有显示器
  • 资源效率. 运行多个抓取器时内存使用较低

如果您正在调试并想看看Selenium在做什么,只需删除–headless参数。Chrome将可见地打开,您可以观察它导航并与页面交互。

使用driver.FindElements()提取元素

一旦页面加载并执行JavaScript,您可以像使用HtmlAgilityPack一样提取数据,但使用Selenium的API。

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
var options = new ChromeOptions();
options.AddArgument("--headless");
options.AddArgument("--disable-gpu");
var driver = new ChromeDriver(options);
try
{
driver.Navigate().GoToUrl("https://quotes.toscrape.com/js/");
// Wait for JavaScript to load content (important!)
Thread.Sleep(2000); // Simple wait
// Find all quote containers
var quoteElements = driver.FindElements(By.CssSelector("div.quote"));
Console.WriteLine($"Found {quoteElements.Count} quotes\n");
foreach (var quoteElement in quoteElements)
{
// Extract text from nested elements
var text = quoteElement.FindElement(By.CssSelector("span.text")).Text;
var author = quoteElement.FindElement(By.CssSelector("small.author")).Text;
// Extract tags (multiple elements)
var tagElements = quoteElement.FindElements(By.CssSelector("a.tag"));
var tags = tagElements.Select(t => t.Text).ToList();
Console.WriteLine($"Quote: {text}");
Console.WriteLine($"Author: {author}");
Console.WriteLine($"Tags: {string.Join(", ", tags)}");
Console.WriteLine("---");
}
}
finally
{
driver.Quit(); // Clean up browser process
}

脚本启动浏览器,导航到页面,等待元素动态加载,然后提取引用、作者名称和标签,最后在终端中打印它们。

icon_check-circle

跳过建造,开始刮削

Decodo的网页抓取API通过简单的HTTP请求返回结构化数据——无需构建或维护任何抓取工具。

好消息是,Selenium支持CSS选择器和XPath。根据偏好选择。

CSS选择器:

driver.FindElement(By.CssSelector("div.quote"));
driver.FindElement(By.CssSelector("span.text"));
driver.FindElement(By.CssSelector("a[href='/author/Albert-Einstein']"));

XPath选择器:

driver.FindElement(By.XPath("//div[@class='quote']"));
driver.FindElement(By.XPath("//span[@class='text']"));
driver.FindElement(By.XPath("//a[contains(@href, 'Einstein')]"));

提取属性

需要href、src或其他属性?使用GetAttribute():

var authorLink = quoteElement.FindElement(By.CssSelector("a"));
var authorUrl = authorLink.GetAttribute("href");
Console.WriteLine($"Author URL: {authorUrl}");

显式等待

代码中的Thread.Sleep(2000)是等待JavaScript执行的粗略方法。它有效,但浪费时间。Selenium提供显式等待,轮询直到元素出现:

using OpenQA.Selenium.Support.UI;
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(d => d.FindElements(By.CssSelector("div.quote")).Count > 0);

这最多等待10秒,但一旦找到元素就继续。比盲目睡眠效率高得多。

导出和结构化抓取的数据

打印到控制台对测试很好,但真正的项目需要您可以分析、共享或导入数据库的结构化数据。专业方法: 定义模型类,填充集合,并导出到CSV。

我们将继续上一节的Selenium示例并添加适当的数据导出。无论您是使用HtmlAgilityPack还是Selenium进行抓取,此模式都有效,导出逻辑保持不变。

在C#中创建数据模型类

不要玩弄松散的字符串,创建一个代表您正在抓取的内容的类。对于我们的引用示例:

public class Quote
{
public string Text { get; set; }
public string Author { get; set; }
public string Tags { get; set; }
public string Url { get; set; }
}

类很重要,因为它们的强类型在编译时而不是运行时捕获错误。如果您拼错了属性名称,编译器会立即注意到。您还可以获得IntelliSense支持、重构工具以及数据结构的精确文档。

使用CsvWriter.WriteRecords()写入CSV

现在让我们修改Selenium抓取器以填充Quote对象列表并导出它们:

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using CsvHelper;
using System.Globalization;
public class Quote
{
public string Text { get; set; }
public string Author { get; set; }
public string Tags { get; set; }
public string Url { get; set; }
}
class Program
{
static void Main()
{
var options = new ChromeOptions();
options.AddArgument("--headless");
options.AddArgument("--disable-gpu");
var driver = new ChromeDriver(options);
var quotes = new List<Quote>();
try
{
driver.Navigate().GoToUrl("https://quotes.toscrape.com/js/");
Thread.Sleep(2000); // Wait for JavaScript to load
var quoteElements = driver.FindElements(By.CssSelector("div.quote"));
foreach (var quoteElement in quoteElements)
{
var text = quoteElement.FindElement(By.CssSelector("span.text")).Text;
var author = quoteElement.FindElement(By.CssSelector("small.author")).Text;
var tagElements = quoteElement.FindElements(By.CssSelector("a.tag"));
var tags = string.Join(", ", tagElements.Select(t => t.Text));
var authorLink = quoteElement.FindElement(By.CssSelector("a"));
var url = authorLink.GetAttribute("href");
quotes.Add(new Quote
{
Text = text,
Author = author,
Tags = tags,
Url = url
});
}
Console.WriteLine($"Scraped {quotes.Count} quotes. Writing to CSV...");
// Write to CSV
using (var writer = new StreamWriter("quotes.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(quotes);
}
Console.WriteLine("Export complete! Check quotes.csv");
}
finally
{
driver.Quit();
}
}
}

脚本执行以下操作:

  1. 将所有<Quote>抓取到List中,而不是立即打印
  2. StreamWriter创建CSV文件
  3. CsvHelper的CsvWriter自动处理格式化、转义和标题
  4. WriteRecords()一次调用序列化整个列表,无需循环,无需手动格式化
  5. using语句确保文件正确关闭,即使发生异常

使用dotnet run命令运行此程序。您将在项目目录中获得一个quotes.csv文件。

处理CultureInfo和UTF-8 BOM以实现Excel兼容性

注意到CultureInfo.InvariantCulture参数了吗?这确保了一致的数字和日期格式,无论您系统的区域设置如何。没有它,德语系统可能使用逗号表示小数,而美国系统使用句点。不变文化使一切保持标准化。

Excel UTF-8问题

Excel有一个怪癖: 它不识别UTF-8文件,除非它们以字节顺序标记(BOM)开头。没有BOM,当您在Excel中打开CSV时,特殊字符(é、ñ、中文)显示为乱码。这是修复方法:

using (var writer = new StreamWriter("quotes.csv", false, new UTF8Encoding(true)))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(quotes);
}

new UTF8Encoding(true)参数添加BOM。现在Excel正确解释UTF-8字符。

总结

您已经完成了一个完整的抓取工作流程,证明了C#对于生产就绪的网络自动化是可靠的。通过添加异步抓取、代理和错误处理,您的设置可以轻松处理现实世界的规模。接下来: 征服更棘手的网站,让数据向您的代码低头。

使用动态住宅代理实现更智能的网页抓取

解锁可靠的轮换IP,让您的抓取操作保持快速、隐蔽且不中断。

关于作者

Zilvinas Tamulis

技术文案

作为一名拥有 4 年以上工作经验的技术作家,Žilvinas 将自己在多媒体和计算机设计方面的学习与创建用户手册、指南和技术文档方面的实际专业知识相结合。他的工作包括利用 JavaScript、PHP 和 Python 的实践经验,开发每天有数百人使用的网络项目。


通过 LinkedIn 与 Žilvinas 联系。

Decodo 博客上的所有信息均按原样提供,仅供参考。对于您使用 Decodo 博客上的任何信息或其中可能链接的任何第三方网站,我们不作任何陈述,也不承担任何责任。

相关文章

如何使用LlamaIndex和网页抓取构建生产就绪的RAG(2025指南)

当生产RAG依赖过时的静态知识时就会失败。本指南向您展示如何构建抓取实时网络数据、与LlamaIndex集成并在生产中实际存活的RAG系统。您将学习架构弹性抓取管道、为数百万文档优化向量存储,以及部署大规模提供实时智能的系统。

Zilvinas Tamulis

12月 10日, 2025年

16 分钟阅读

n8n网页抓取自动化完整指南

如果您已厌倦为了获取网页数据而勉强拼凑复杂脚本,那么本n8n网页抓取教程正适合您。您将了解如何使用n8n进行网页抓取、为何它优于自制抓取工具,以及入门所需知识。特别适合希望无痛实现数据提取自动化的开发人员和编程初学者。

Zilvinas Tamulis

11月 18日, 2025年

18 分钟阅读

Playwright 网络抓取: 实用教程

网络抓取就像没有剧本的戏剧导演——难以预测、杂乱无章。这就是 Playwright 的用武之地:它是一款功能强大的无头浏览器自动化工具,能让现代动态网站刮擦变得前所未有的顺畅。在本实用教程中,您将学习如何使用 Playwright 从任何网页中可靠地提取数据。

Zilvinas Tamulis

6月 19日, 2025年

8 分钟阅读

常见问题

最流行的C#网页抓取库是什么?

HtmlAgilityPack是大多数C#网页抓取项目的首选库。它轻量、文档完善,并开箱即用地处理带有XPath支持的静态HTML解析。对于JavaScript密集型网站,Selenium和PuppeteerSharp是标准选择,尽管它们在资源上更重。

如何设置C#网页抓取环境?

从Microsoft的官方网站安装.NET SDK,然后获取带有C# Dev Kit扩展的Visual Studio Code。使用dotnet new console创建一个新的控制台项目,通过dotnet add package HtmlAgilityPack添加HtmlAgilityPack,您就可以开始抓取了。在任何操作系统上整个设置大约需要10分钟。

我应该使用哪个库来抓取JavaScript呈现的页面?

当数据在初始页面呈现后加载时使用Selenium或PuppeteerSharp。HtmlAgilityPack看不到动态加载的内容,因为它只解析初始HTML响应。Selenium经过更多实战考验,而如果您熟悉Node.js的Puppeteer,PuppeteerSharp提供更清晰的API。

如何在C#中将抓取的数据导出到CSV文件?

使用dotnet add package CsvHelper安装CsvHelper,为您的数据创建一个模型类,然后使用CsvWriter.WriteRecords()将您的列表转储到文件中。记住使用CultureInfo.InvariantCulture和带有BOM的UTF-8编码,如果您希望Excel在不破坏特殊字符的情况下打开它。

C#网页抓取的一些最佳实践是什么?

始终检查robots.txt并尊重速率限制,在请求之间添加延迟,这样您就不会猛击服务器。在HTTP调用和DOM选择周围使用try-catch块,以防网站结构在没有警告的情况下发生变化。考虑使用像Decodo网页抓取API这样的服务用于生产场景,在这些场景中,您需要代理、CAPTCHA处理和可靠性,而无需维护麻烦。

© 2018-2025 decodo.cn(原名 smartproxy.com)。版权所有 津ICP备2022004334号-2