在本文中,我将向你展示如何用 C# 构建一个网络爬虫。我们会从零开始,一步一步来。到最后,你将拥有一个高效、可扩展的爬虫,用于收集所需数据。
让我们开始吧!
什么是网络爬虫?
网络爬虫,也称为 spider 或 bot,是一种自动化程序,会系统地浏览网页、发现链接并收集数据。与针对特定数据提取的网页抓取不同,网页爬取侧重于浏览网站并构建其内容的结构化地图。爬虫还可以集成抓取功能,在探索链接的同时提取相关数据。
在这里比较网页爬取和网页抓取。
构建网络爬虫的替代方案
如果构建和维护网络爬虫让你感到负担过重,Bright Data 提供了强大的替代方案来简化你的工作流。使用Web 爬虫工具 API进行轻松的结构化数据提取,或访问根据你的需求定制的即用型数据集。这些解决方案可以节省时间、轻松扩展,并包含 CAPTCHA 破解、IP 轮换以及遵守隐私法律等功能——让你专注于分析数据,而不是收集数据。
我与 Bright Data 没有任何关联,这只是一个建议。
用 C# 构建网络爬虫的先决条件
开始之前,请确保你具备以下工具和库:
.NET SDK(版本 8 或更高版本): 从官方 Microsoft .NET 网站下载并安装最新版本。
IDE: 使用 Visual Studio 2022 或安装了 C# 扩展的 Visual Studio Code。
NuGet Package Manager: 随 Visual Studio 提供,用于安装 Html Agility Pack 和 CsvHelper 等依赖项。
步骤 1:设置环境
首先创建一个新的控制台应用程序:
mkdir web-crawler
cd web-crawler
dotnet new console - framework net8.0
安装依赖项
使用 NuGet 添加以下库:
Html Agility Pack:用于解析 HTML。
dotnet add package HtmlAgilityPack
Html Agility Pack CSS Selectors:简化使用 CSS 选择器选择元素的过程。
dotnet add package HtmlAgilityPack.CssSelectors
CsvHelper:用于将数据导出到 CSV 文件。
dotnet add package CsvHelper
步骤 2:编写基础爬虫
加载网页
设置程序以获取并解析网页:
using HtmlAgilityPack;
class Program
{
static void Main(string[] args)
{
var web = new HtmlWeb();
var document = web.Load("https://example.com");
Console.WriteLine("Page loaded successfully!");
}
}
使用以下命令运行应用程序:
dotnet run
发现链接
扩展代码以识别页面上的链接。使用 HtmlAgilityPack 定位所有 <a> 元素并提取它们的 href 属性:
var links = document.DocumentNode.SelectNodes("//a[@href]");
foreach (var link in links)
{
var url = link.GetAttributeValue("href", string.Empty);
Console.WriteLine($"Found URL: {url}");
}
步骤 3:管理爬取过程
要系统地爬取多个页面,请维护一个待访问 URL 队列,以及一个已发现 URL 列表以避免重复。
实现 URL 队列
使用 Queue 存放待访问的 URL,并使用 HashSet 跟踪已访问的 URL:
var urlsToVisit = new Queue<string>();
var visitedUrls = new HashSet<string>();
urlsToVisit.Enqueue("https://example.com");
while (urlsToVisit.Count > 0)
{
var currentUrl = urlsToVisit.Dequeue();
if (visitedUrls.Contains(currentUrl)) continue;
visitedUrls.Add(currentUrl);
Console.WriteLine($"Crawling: {currentUrl}");
var currentDocument = web.Load(currentUrl);
var links = currentDocument.DocumentNode.SelectNodes("//a[@href]");
if (links == null) continue;
foreach (var link in links)
{
var url = link.GetAttributeValue("href", string.Empty);
if (!visitedUrls.Contains(url))
{
urlsToVisit.Enqueue(url);
}
}
}
第 4 步:从页面中提取数据
结构化数据
定义一个 Product 类来存储抓取到的数据:
public class Product
{
public string Name { get; set; }
public string Price { get; set; }
public string ImageUrl { get; set; }
}
抓取产品
更新爬虫,以便在每个页面上查找并处理产品元素:
var products = new List<Product>();
foreach (var productNode in currentDocument.DocumentNode.SelectNodes("//li[@class='product']"))
{
var name = productNode.SelectSingleNode(".//h2").InnerText.Trim();
var price = productNode.SelectSingleNode(".//span[@class='price']").InnerText.Trim();
var imageUrl = productNode.SelectSingleNode(".//img").GetAttributeValue("src", string.Empty);
products.Add(new Product { Name = name, Price = price, ImageUrl = imageUrl });
Console.WriteLine($"Found product: {name}");
}
第 5 步:将数据保存到 CSV 文件
使用 CsvHelper 将收集到的产品数据导出到 CSV 文件:
using CsvHelper;
using System.Globalization;
using System.IO;
using (var writer = new StreamWriter("products.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csv.WriteRecords(products);
}
运行应用程序,生成一个包含所有抓取数据的 products.csv 文件。
第 6 步:优化爬虫
并行爬取:使用 Task.Run 并发爬取多个页面。
处理动态内容:对 JavaScript 渲染的页面使用 PuppeteerSharp。
避免被封锁:轮换 user agents、遵守 robots.txt,并引入延迟。
结论
用 C# 构建网络爬虫,核心就是探索网页、提取你需要的数据,并确保它稳定运行。有了这份指南,你将能够应对任何网页数据项目。祝你好运,也祝你爬取愉快!
有任何问题吗?欢迎在评论中告诉我!
对其他网页抓取指南感兴趣?
使用 Scrapy 进行网页抓取
使用 Selenium 进行网页抓取
用于网页抓取的 JavaScript 与 Python 对比
使用 Python lxml 进行网页抓取
使用 Excel 进行网页抓取
使用 Python 进行网页抓取
使用 C# 进行网页抓取
抓取 Amazon 畅销榜
使用 Google Sheets 进行网页抓取
绕过 Cloudflare 进行网页抓取
请求限流指南
更多精彩文章,请访问我的个人主页 — Data Journal ❤️