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

前言

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

在这里插入图片描述

什么是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+XmacOS上为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=" P A T H : 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           # 您的主入口点
├── WebScraper.csproj    # 项目配置文件
├── obj/                 # 中间构建文件(忽略这个)
└── bin/                 # 编译的输出放在这里

选择正确的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("页面加载成功!");
Console.WriteLine($"标题: {doc.DocumentNode.SelectSingleNode("//title").InnerText}");

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

dotnet run

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

使用SelectNodes()和SelectSingleNode()的XPath

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

基本XPath模式:

// 选择所有匹配的元素
var quoteNodes = doc.DocumentNode.SelectNodes("//div[@class='quote']");

// 选择第一个匹配的元素
var firstQuote = doc.DocumentNode.SelectSingleNode("//div[@class='quote']");

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

让我们提取实际数据:

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)
{
    // 使用相对XPath提取嵌套元素(以.开头)
    var text = quoteNode.SelectSingleNode(".//span[@class='text']").InnerText;
    var author = quoteNode.SelectSingleNode(".//small[@class='author']").InnerText;
    
    Console.WriteLine($"引用: {text}");
    Console.WriteLine($"作者: {author}");
    Console.WriteLine("---");
}

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

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

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

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

那些"'"是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;
    
    // 将HTML实体解码为可读文本
    text = HtmlEntity.DeEntitize(text);
    
    Console.WriteLine($"引用: {text}");
    Console.WriteLine($"作者: {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;

// 配置Chrome选项
var options = new ChromeOptions();
options.AddArgument("--headless");      // 无GUI运行
options.AddArgument("--disable-gpu");   // 禁用GPU加速(建议用于无头)
options.AddArgument("--no-sandbox");    // 绕过操作系统安全模型(在某些环境中需要)

// 使用这些选项启动Chrome
var driver = new ChromeDriver(options);

try
{
    driver.Navigate().GoToUrl("https://quotes.toscrape.com/js/");
    Console.WriteLine($"页面标题: {driver.Title}");
}
finally
{
    driver.Quit();  // 总是关闭浏览器
}

使用以下命令运行:

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/");
    
    // 等待JavaScript加载内容(重要!)
    Thread.Sleep(2000);  // 简单等待
    
    // 查找所有引用容器
    var quoteElements = driver.FindElements(By.CssSelector("div.quote"));
    
    Console.WriteLine($"找到{quoteElements.Count}条引用\n");
    
    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 = tagElements.Select(t => t.Text).ToList();
        
        Console.WriteLine($"引用: {text}");
        Console.WriteLine($"作者: {author}");
        Console.WriteLine($"标签: {string.Join(", ", tags)}");
        Console.WriteLine("---");
    }
}
finally
{
    driver.Quit();  // 清理浏览器进程
}

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

元素选择: CSS选择器vs XPath

在前面的示例中,脚本使用CSS选择器来查找内容。但是,这并不总是抓取页面的完美方式。虽然CSS选择器更快更干净,但XPath对于复杂的树遍历更灵活,特别是当您需要跳转CSS无法轻松到达的父节点或兄弟节点时。

好消息是,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($"作者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);  // 等待JavaScript加载
            
            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($"抓取了{quotes.Count}条引用。正在写入CSV...");
            
            // 写入CSV
            using (var writer = new StreamWriter("quotes.csv"))
            using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
            {
                csv.WriteRecords(quotes);
            }
            
            Console.WriteLine("导出完成!检查quotes.csv");
        }
        finally
        {
            driver.Quit();
        }
    }
}

脚本执行以下操作:

  1. 将所有引用抓取到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#对于生产就绪的网络自动化是可靠的。通过添加异步抓取、代理和错误处理,您的设置可以轻松处理现实世界的规模。接下来: 征服更棘手的网站,让数据向您的代码低头。


常见问题解答

最流行的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处理和可靠性,而无需维护麻烦。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值