总体来说,网络抓取非常强大。它允许你大规模收集和处理数据。你可以监控价格、收集用户评论、分析竞争对手、查看商业趋势和新闻等。使用 C# 进行网络抓取是一种无价的商业工具,它不仅简单,而且性能优越。
今天,我们将探讨如何使用 C# 和无头浏览器抓取网站。从安装 IDE 到数据收集,涵盖所有内容。此外,你还将学习如何在不被封锁的情况下进行网络抓取。
你能用 C# 进行网络抓取吗?
当然,你可以用 C# 进行网络抓取。你可以使用代码库、解析器或无头浏览器。无头浏览器,如 Playwright,允许你通过代码控制浏览器,因此你可以模拟用户行为、收集数据、与页面互动并截图,就像普通用户一样。
C# 适合做网络抓取吗?
C# 非常适合做网络抓取。它性能出色,入门也非常简单。另一个优势是有庞大的社区,提供大量的代码库和示例。
遇到同样问题的人很容易找到,所以你不会花太多时间去解决全新的问题。
最好的 C# 网络抓取库是什么?
最好的 C# 网络抓取库是 Playwright。它允许你从任何你想要的网站收集数据并与之互动。
但在深入了解之前,让我们看看为什么使用像 Playwright dotnet 这样的无头浏览器是最佳选择。
在 C# 网络抓取方面,主要有四种选择:
- 使用 C# cURL 或类似工具抓取原始 HTML 内容,并使用正则表达式——这不是一个可靠的解决方案,因为正则表达式很难构建,而且很容易失效。
- 使用 C# cURL 获取 HTML 内容,然后将这些数据发送到解析器,如 HTML Agility Pack——这也不是一个很好的解决方案。解析器只能模拟浏览器的部分功能,它们不加载动态内容,可能无法加载你需要的内容。
- 加载 XHR 请求或使用 API——如果可用的话,这可能效果不错。但大多数网站不允许你通过 API 访问所有你需要的内容。
- 使用无头浏览器——这是最佳选择。
无头浏览器允许你通过代码模拟真实用户。因此,你可以用代码打开浏览器、加载 URL、与页面互动、点击链接、填写表单、点击按钮和滚动页面。然后你可以从页面读取一些数据或截图。
一切都是自动化的。
但在 C# 无头浏览器方面,主要有两个选择——PuppeteerSharp 和 Playwright dotnet。
什么是 PuppeteerSharp?
PuppeteerSharp 是一个 C# .NET 库,用于访问无头浏览器。它的工作方式与其他语言的 Puppeteer 类似,允许你通过代码访问浏览器 API 并控制它们以执行自动化任务。
Playwright 比 Puppeteer 更好吗?
Playwright 提供更多的 API 选项,而且比 Puppeteer 更容易使用。微软支持 Playwright 项目,因此他们有很多资源来推出一个非常强大的多语言产品,包括 C#。
因此,我们将在本教程中使用 Playwright。
网站能检测到网络抓取吗?
如果开发者不隐藏他们的活动,网站可以检测到网络抓取。你需要使用代理和浏览器元数据等工具,确保你的访问看起来是合法的。
值得一提的是,网络抓取是完全合法的。但许多网站试图阻止它。
他们要么通过识别奇怪的用户元数据,要么通过识别可疑的浏览模式来实现这一点。
第一部分是关于请求看起来是否合法。一些库不发送用户元数据,如浏览器、操作系统或语言。因此,目标网站可以查看这些请求并认为它们是可疑的。毕竟,大多数浏览器都会发送这些数据,所以这很可能是由机器人发出的请求。
不过,你不需要担心这个问题。Playwright 连接到真实浏览器(Firefox、Chrome 和 Chromium),所以所有请求看起来和感觉都很合法,因为它们确实是合法的。
网站所有者也可以查看你的浏览模式。如果你访问了太多页面,或者在特定时间访问特定页面,这可能看起来很奇怪。不过,他们只能通过你的 IP 地址追踪这些请求。
如果你使用不同的 IP 地址,就像一个新访客。因此,你可以使用代理。通过它,你可以每次使用不同的 IP 地址连接到网站。所以,他们甚至不会知道你正在加载多个页面。在这里我们推荐使用住宅代理进行网络抓取。
一旦你注册了住宅代理服务,就可以访问其客户端区域。我们以IPRoyal为例,在其中,你可以看到你的连接细节如下所示:
使用 C# 进行网络抓取
为了使用 C# 抓取页面,我们需要安装一个 IDE,创建一个新项目,并引入 Playwright。然后你就可以开始编写代码,加载浏览器,使用代理,截图和提取数据。
现在让我们逐步完成这些步骤。
步骤 1 — 网络抓取项目设置
你需要一个 IDE 来编辑代码。如果你还没有,可以使用 Visual Studio,这是一个适用于 Windows、macOS 和 Linux 的免费选项。
安装好 IDE 后,创建一个新项目来添加你的代码。你可以使用“Web 应用程序(模型-视图-控制器)”项目类型:
然后,为了使用无头浏览器抓取页面,你需要 Playwright。你可以通过以下方式将其包含在你的项目中:工具 > 管理 NuGet 包 > 搜索 Playwright:
确保勾选 “Microsoft.Playwright” 包,然后点击 “添加包”。
为了确保它正常工作,编辑 /Controllers/HomeController.cs 文件。将你当前的 Index() 替换为以下代码:
public async Task<IActionResult> Index() { var proxy = new Proxy { Server = "http://geo.iproyal.com:12321", Username = "username", Password = "password" }; using var playwright = await Playwright.CreateAsync(); await using var browser = await playwright.Chromium.LaunchAsync(new() { Proxy = proxy }); var page = await browser.NewPageAsync(); await page.GotoAsync("https://ipv4.icanhazip.com/"); await page.ScreenshotAsync(new() { Path = "screenshot.png" }); return View(); }
一般来说,这段代码会在你加载服务器主页时执行。
代码的前几行创建了一个变量来存储代理信息。确保用你自己的 URL、用户名和密码替换这些变量。
然后,你创建一个新的 Playwright 实例。这是用于加载所有其他内容的主要实例。
接下来,你将使用之前加载的代理选项加载一个 Chromium 浏览器。
接下来的几行代码用于打开一个新的浏览器标签页,导航到一个页面并截图。
运行这段代码后,你会在项目的文件夹中得到一个截图。在截图中,你会看到代理的 IP 地址,而不是你自己的。
这就是使用 Playwright C# 进行网络抓取的截图:
这是我直接访问https://ipv4.icanhazip.com/时看到的:
这意味着 C# 网络抓取请求是通过代理进行的。让我们进一步探索你的 C# 网络抓取工具。
步骤 2 — 截图
你可以用以下代码进行简单截图:
await page.ScreenshotAsync(new() { Path = "screenshot.png" });
但还有许多其他选择可供选择。
例如,你可以用下面的代码截图整个页面:
await Page.ScreenshotAsync(new() { Path = "screenshot.png", FullPage = true, });
你甚至可以用下面的代码截取一个特定元素的截图:
await page.Locator(".header").ScreenshotAsync(new() { Path = "screenshot.png" });
注意,你是通过定位器(locator)来访问 ScreenshotAsync,而不是通过页面(page)。这也是你选择页面元素的方式。在这个例子中,代码片段选择了“.header”部分并进行了截图。
步骤 3 – 如何使用 C# 从网站读取数据
如果你想从一个元素中提取数据,你需要先定位它。因此,你可以使用定位器在你的 C# 网络抓取工具中从页面提取数据。
你可以通过以下方式选择元素:
- 文本内容
- CSS 选择器
- 结合文本和 CSS 选择器
- xPath
- React 选择器
- Vue 选择器
- 布局位置(如 X 的左边)
以下是一些示例:
文本选择器
使用这个选项,你可以根据元素的文本内容进行选择。例如,你可以选择一个文本为“home”的按钮并点击它。
因此,你不需要知道该元素的确切 CSS 选择器、xPath 或其他任何信息。
如果页面结构变化较大,这个方法非常方便。你可以使用以下代码:
await page.Locator("text=Home").ClickAsync();
或者你甚至可以使用它的简写版本,用单引号括在双引号中:
await page.Locator("’Home’").ClickAsync();
假定这是一个文本选择器。
你也可以使用精确匹配和部分匹配,使用引号表示精确匹配,使用” has-text “选择器表示部分匹配。
await page.Locator("a:has-text(‘Home’)").ClickAsync();
CSS选择器
这些都很简单,但非常强大。几乎任何你能想到的CSS选择器都是可以使用的,包括伪选择器。
你可以使用简单的ID选择器:
await page.Locator("#button").ClickAsync();
你还可以使用复杂的CSS选择器组合:
await page.Locator("article:has(div.gallery)").TextContentAsync();
顺便说一下,您可以使用上面的TextContentAsync()函数从元素加载内容。
Playwright vs Puppeteersharp xpath
XPath 是另一种强大的选择器。你可以获取任何页面元素的 xPath。打开浏览器检查器,检查一个元素,然后在浏览器检查器中右键点击该元素,选择复制 > xPath。
这为该元素提供了唯一的选择器。
然后你可以在你的无头浏览器中使用它,无论是剧作家还是木偶夏普。
await page.Locator("a >> nth=-1").ClickAsync();
这将单击页面上的最后一个链接。
常见问题
C# 只有一个编译单元可以有顶级语句
这通常发生在你的应用程序有多个入口点时。确保你没有创建额外的文件,并确保你没有创建多个初始化服务器的函数。
错误:Playwright 不支持 mac12 上的 Chromium
这通常发生在你有一个旧版本的 Chromium,或者你的项目由于某些原因无法访问 Chromium。
更新所有内容,然后仔细检查你的计算机上是否有 Chromium。
Microsoft.Playwright.PlaywrightException: 可执行文件不存在
这发生在你的计算机上还没有 Chromium 时。
打开你的项目文件夹,然后进入 /bin/debug。在其中你会看到你需要使用的实际文件夹名称。
这是因为错误信息告诉你运行 “pwsh bin/Debug/netX/playwright.ps1 install”。所以你可以用实际的文件夹名称替换 X。
此外,如果你没有 PowerShell,你需要安装它。
结 论
今天我们学习了使用 C# 进行网络抓取。我们从简单的问题,如当前的网络抓取方法,到复杂的任务,如基于复杂 CSS 选择器加载元素,都进行了探讨。
希望你喜欢这次学习,我们下次再见!