C#中的Web抓取:避免被阻挡

news2025/1/16 17:27:16

C# 是一种广泛应用于企业级项目和应用程序的多功能编程语言。它源自 C 系列语言,具有高效和强大的特点,使其成为任何开发人员工具包中不可或缺的一部分。

由于其广泛的应用,C# 提供了大量的工具,使开发人员能够解决复杂的解决方案,网络爬虫也不例外。

在本教程中,我们将带您一步步创建一个简单的网络爬虫,使用 C# 及其用户友好的爬虫库。此外,我们还将揭示一个巧妙的技巧,只需一行代码即可帮助您避免被封锁。准备好了吗?我们开始吧!

以下是文章的目录:

目录

  1. 网络爬虫简介
    • 为什么选择 C# 而不是 C 进行网络爬虫?
  2. 设置您的环境
    • 前提条件
    • 安装库
    • 在 Visual Studio 中创建一个 C# 网络爬虫项目
  3. 使用 C# 进行基本的网络爬虫
    • 发出 HTTP 请求
    • 解析 HTML 内容
    • 高级 HTML 解析
  4. 如何处理爬取的数据
  5. 在网络爬虫中处理 CAPTCHA
    • 集成 CAPTCHA 解决方案
    • CapSolver 示例代码
  6. 结论

1. 网络爬虫简介

网络爬虫是自动从网站提取信息的过程。这可以用于各种目的,包括数据分析、市场研究和竞争情报。然而,许多网站实现了检测和阻止自动爬虫尝试的机制,因此使用复杂的技术来避免被封锁是至关重要的。

为什么选择 C# 而不是 C 进行网络爬虫?

网络爬虫通常涉及与网页元素交互、管理 HTTP 请求以及处理数据提取和解析。虽然 C 是一种强大且高效的语言,但它缺乏使网络爬虫更容易和高效的内置库和现代功能。以下是 C# 更适合网络爬虫的一些原因:

  • 丰富的库:C# 拥有丰富的库,如 HtmlAgilityPack 用于 HTML 解析,Selenium 用于浏览器自动化,这些都简化了爬虫过程。
  • 异步编程:C# 的 async 和 await 关键字允许进行高效的异步操作,这对于同时处理多个网络请求至关重要。
  • 易用性:C# 的语法比 C 更现代和用户友好,使开发过程更快且错误更少。
  • 集成:C# 无缝集成到 .NET 框架中,提供了强大的工具和服务,用于构建强大的应用程序。

是否因为反复无法完全解决恼人的验证码而感到困扰?

通过 Capsolver AI 驱动的自动网络解封技术,体验无缝自动验证码解决方案!

领取您的 优惠码,获取最佳验证码解决方案;CapSolver:WEBS。兑换后,您每次充值将获得额外 5% 的奖励,无限制。

2. 设置您的环境

在我们开始爬取之前,我们需要设置开发环境。以下是设置方法:

前提条件

  • Visual Studio:免费的 Visual Studio 2022 Community 版即可。
  • .NET 6+:任何大于或等于 6 的 LTS 版本都可以。
  • HtmlAgilityPack 库用于 HTML 解析
  • RestSharp 库用于发出 HTTP 请求

在 Visual Studio 中创建一个 C# 网络爬虫项目

在 Visual Studio 中设置项目
  1. 打开 Visual Studio,点击“创建新项目”选项。

  1. 在“创建新项目”窗口中,从下拉列表中选择“C#”选项。指定编程语言后,选择“控制台应用程序”模板,然后点击“下一步”。

  1. 将您的项目命名为 StaticWebScraping,点击“选择”,并选择 .NET 版本。如果您已安装 .NET 6.0,Visual Studio 应该已经为您选择好了。

  1. 点击“创建”按钮初始化您的 C# 网络爬虫项目。Visual Studio 将初始化一个包含 App.cs 文件的 StaticWebScraping 文件夹。这个文件将存储您的 C# 网络爬虫逻辑:
namespace WebScraping {
    public class Program {
        public static void Main() {
            // 爬虫逻辑...
        }
    }
}

现在是时候了解如何在 C# 中构建一个网络爬虫了!

3. 使用 C# 进行基本的网络爬虫

在本节中,我们将创建一个 C# 应用程序,该应用程序向网站发出 HTTP 请求,获取 HTML 内容,并解析它以提取信息。

发出 HTTP 请求

首先,让我们创建一个基本的 C# 应用程序,该应用程序向网站发出 HTTP 请求并获取 HTML 内容。

using System;
using RestSharp;

class Program
{
    static void Main()
    {
        // 创建一个新的 RestClient 实例,目标 URL
        var client = new RestClient("https://www.example.com");
        
        // 创建一个新的 RestRequest 实例,使用 GET 方法
        var request = new RestRequest(Method.GET);
        
        // 执行请求并获取响应
        IRestResponse response = client.Execute(request);

        // 检查请求是否成功
        if (response.IsSuccessful)
        {
            // 打印响应的 HTML 内容
            Console.WriteLine(response.Content);
        }
        else
        {
            Console.WriteLine("获取内容失败");
        }
    }
}

解析 HTML 内容

接下来,我们将使用 HtmlAgilityPack 解析 HTML 内容并提取我们需要的信息。

using HtmlAgilityPack;
using System;
using RestSharp;

class Program
{
    static void Main()
    {
        // 创建一个新的 RestClient 实例,目标 URL
        var client = new RestClient("https://www.example.com");
        
        // 创建一个新的 RestRequest 实例,使用 GET 方法
        var request = new RestRequest(Method.GET);
        
        // 执行请求并获取响应
        IRestResponse response = client.Execute(request);

        // 检查请求是否成功
        if (response.IsSuccessful)
        {
            // 将 HTML 内容加载到 HtmlDocument 中
            var htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(response.Content);

            // 选择匹配指定 XPath 查询的节点
            var nodes = htmlDoc.DocumentNode.SelectNodes("//h1");
            
            // 遍历选定的节点并打印它们的内文本
            foreach (var node in nodes)
            {
                Console.WriteLine(node.InnerText);
            }
        }
        else
        {
            Console.WriteLine("获取内容失败");
        }
    }
}

高级 HTML 解析

让我们更进一步,从一个示例网站抓取更复杂的数据。假设我们想从一个博客页面抓取文章列表,包括标题和链接。

using HtmlAgilityPack;
using System;
using RestSharp;

class Program
{
    static void Main()
    {
        // 创建一个新的 RestClient 实例,目标 URL
        var client = new RestClient("https://www.example.com/blog");
        
        // 创建一个新的 RestRequest 实例,使用 GET 方法
        var request = new RestRequest(Method.GET);
        
        // 执行请求并获取响应
        IRestResponse response = client.Execute(request);

        // 检查请求是否成功
        if (response.IsSuccessful)
        {
            // 将 HTML 内容加载到 HtmlDocument 中
            var htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(response.Content);

            // 选择匹配指定 XPath 查询的节点
            var nodes = htmlDoc.DocumentNode.SelectNodes("//div[@class='post']");

            // 遍历选定的节点并提取标题和链接
            foreach (var node in nodes)```csharp
{
    // 遍历选定的节点并提取标题和链接
    foreach (var node in nodes)
    {
        var titleNode = node.SelectSingleNode(".//h2/a");
        var title = titleNode.InnerText;
        var link = titleNode.Attributes["href"].Value;
        
        Console.WriteLine("标题: " + title);
        Console.WriteLine("链接: " + link);
        Console.WriteLine();
    }
}
else
{
    Console.WriteLine("获取内容失败");
}
}
}

在这个示例中,我们抓取了一个博客页面,选择每篇文章的标题和链接。XPath 查询 //div[@class='post'] 用于定位单独的帖子。

4. 如何处理爬取的数据

  1. 将其存储在数据库中,以便随时查询。
  2. 将其转换为 JSON 格式,并用它调用各种 API。
  3. 将其转换为人类可读的格式,如 CSV,可以用 Excel 打开。

这些只是一些示例。关键点是,一旦您在代码中获取了爬取的数据,您可以根据需要使用它。通常,爬取的数据会被转换为更有用的格式,以便您的市场、数据分析或销售团队使用。

然而,请记住,网络爬虫也有其挑战。

5. 在网络爬虫中处理 CAPTCHA

网络爬虫面临的最大挑战之一是处理 CAPTCHA,它们旨在区分人类用户和机器人。如果您遇到 CAPTCHA,您的爬虫脚本需要解决它才能继续。特别是如果您想扩大您的网络爬虫规模,CapSolver 可以通过其高准确率和快速解决的能力帮助您解决任何遇到的 CAPTCHA。

集成 CAPTCHA 解决方案

有几种 CAPTCHA 解决服务可以集成到您的爬虫脚本中。这里,我们将使用 CapSolver 服务。首先,您需要注册 CapSolver 并获取您的 API 密钥。

步骤 1:注册 CapSolver

在您准备好使用 CapSolver 的服务之前,您需要前往用户面板并注册您的账户。

步骤 2:获取您的 API 密钥

注册后,您可以从主页面板获取您的 API 密钥。

CapSolver 示例代码

在您的网络爬虫或自动化项目中使用 CapSolver 非常简单。以下是一个 Python 示例,演示如何将 CapSolver 集成到您的工作流程中:

# pip install requests
import requests
import time

# TODO: 设置您的配置
api_key = "YOUR_API_KEY"  # 您的 CapSolver API 密钥
site_key = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"  # 目标网站的站点密钥
site_url = ""  # 目标网站的页面 URL

def capsolver():
    payload = {
        "clientKey": api_key,
        "task": {
            "type": 'ReCaptchaV2TaskProxyLess',
            "websiteKey": site_key,
            "websiteURL": site_url
        }
    }
    res = requests.post("https://api.capsolver.com/createTask", json=payload)
    resp = res.json()
    task_id = resp.get("taskId")
    if not task_id:
        print("创建任务失败:", res.text)
        return
    print(f"获取任务 ID: {task_id} / 获取结果中...")

    while True:
        time.sleep(3)  # 延迟
        payload = {"clientKey": api_key, "taskId": task_id}
        res = requests.post("https://api.capsolver.com/getTaskResult", json=payload)
        resp = res.json()
        status = resp.get("status")
        if status == "ready":
            return resp.get("solution", {}).get('gRecaptchaResponse')
        if status == "failed" or resp.get("errorId"):
            print("解决失败!响应:", res.text)
            return

token = capsolver()
print(token)

在这个示例中,capsolver 函数向 CapSolver 的 API 发送请求,包含必要的参数,并返回 CAPTCHA 解决方案。这个简单的集成可以在网络爬虫和自动化任务中节省无数的时间和精力。

6. 结论

使用 C# 进行网络爬虫使开发人员能够高效地自动从网站提取数据。通过利用 HtmlAgilityPack 和 RestSharp 等库,以及 CAPTCHA 解决服务如 CapSolver,开发人员可以顺利地浏览网页、解析 HTML 内容,并处理各种挑战。这种能力不仅简化了数据收集过程,还确保了遵守道德爬虫实践,提高了网络爬虫项目在各种应用中的可靠性和可扩展性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1812667.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DeepSpeed Mixture-of-Quantization (MoQ)

属于QAT (Quantization-Aware Training)的一种,训练阶段用量化。 特点是: 1. 从16-bit INT开始训练,逐渐减1bit,训练一些steps就减1bit,直至减至8bit INT; 2. (可选,不一定非用&a…

如何在 ASP.NET Core Web Api 项目中应用 NLog 写日志?

前言 昨天分享了在 .NET Core Console 项目中应用 NLog 写日志的详细例子,有几位小伙伴私信说 ASP.NET Core Web Api 项目中无法使用,其实在 ASP.NET Core Web Api 项目中应用 NLog 写日志,跟 .NET Core Console 项目是有些不一样的&#xf…

css font-family

知乎的font-family的设置理解 -apple-system, BlinkMacSystemFont 这两个值是为了确保在macOS和iOS系统上能够使用系统默认字体进行文本渲染。-apple-system特别为Safari浏览器设计,而BlinkMacSystemFont则主要针对基于Chromium的浏览器(如Chrome&#…

OS进程取样器OS Process Sampler执行CMD/Shell命令

Apache JMeter - Users Manual: Component Reference 1.背景 项目上最近需要测试一种很少用到的DICOM协议,但是网上资料很少,基本上可以总结为三种方案: 直接发送TCP 16进制数据包,但是参数化数据准备难度大通过开发封装jar包发送,需要开发组提供通过发送cmd命令给前置机…

【精选研报】#2形态识别,均线的收敛与发散

下载地址https://pan.baidu.com/s/1L1wPR7kXCb-ZbrgwFKcIvg?pwd8888

Qt线程间的同步(QMutex、QReadWriteLock、QSemaphone、QWaitCondition、信号槽)

同步方法: 1、互斥锁QMutex、函数互斥锁QMutexLocker。 2、读写锁QReadWriteLock、读锁QReadLockerr、写锁QWriteLocker。 3、信号量QSemaphore(QSystemSemaphore支持进程间的同步)。 4、条件变量QWaitConditon。 5、信号槽(第五个…

Jmeter07:函数

1 Jmeter组件:函数 1.1 是什么? 是程序中的封装单元(最小的),封装一些功能实现 1.2 为什么? 优点1:易读 易维护 优点2:实现功能复用 1.3 怎么用? 流程: 1&…

[ADS信号完整性分析]深入理解IBIS AMI模型设计:从基础到实践

在高速数字设计领域,信号完整性(SI)分析对于确保系统性能至关重要。IBIS AMI(Algorithmic Model Interface)模型作为一种强大的工具,能够帮助设计师在系统层面上评估和优化SERDES(串行器/解串器…

【STM32】基于I2C协议的OLED显示(利用U82G库)

【STM32】基于I2C协议的OLED显示(利用U82G库) 文章目录 【STM32】基于I2C协议的OLED显示(利用U82G库)一、实验背景二、U8g2介绍(一)获取(二)简介 三、实践(一)CubexMX配置(二)U8g2配…

【wiki知识库】06.文档管理接口的实现--SpringBoot后端部分

目录 一、🔥今日目标 二、🎈SpringBoot部分类的添加 1.调用MybatisGenerator 2.添加DocSaveParam 3.添加DocQueryVo 三、🚆后端新增接口 3.1添加DocController 3.1.1 /all/{ebokId} 3.1.2 /doc/save 3.1.3 /doc/delete/{idStr} …

Pixi.js学习 (五)动画效果与变量逻辑控制

目录 前言 一、动画效果 1.1 帧频 1.2 帧频函数 二、变量逻辑控制 2.1 定义变量的语法 2.2 使用变量控制逻辑 2.3 使用变量控制追加效果 三、实战 例题一:完成天天酷跑 例题一代码: 总结 前言 为了提高作者的代码编辑水品,作者在使用博客的时…

day35|1005.K次取反后最大化的数组和 134. 加油站135. 分发糖果

文章目录 python语法记录 sort格式 1005.K次取反后最大化的数组和思路方法一方法二 按照绝对值排序 教程🎈✨ 背住 按照绝对值进行降序排序的语法是: 134. 加油站思路方法一 教程解法方法二 暴力求解 135. 分发糖果思路方法一 总结 python语法记录 sort …

【AI大模型】Transformers大模型库(七):单机多卡推理之device_map

目录​​​​​​​ 一、引言 二、单机多卡推理之device_map 2.1 概述 2.2 自动配置,如device_map"auto" 2.3 手动配置,如device_map"cuda:1" 三、总结 一、引言 这里的Transformers指的是huggingface开发的大模型库&#x…

MapTR代码复现-nucenes数据集

前言 本节将对环视车道线MapTR算法进行复现,使用nuscenes-mini数据集! 一、环境配置 1、基础环境: ubuntu20.04,pytorch1.10.0,python3.8,cuda11.3 2、源码下载 下载地址: git clone http…

基础IO(下)

基础IO 1. 磁盘1.1 磁盘的物理结构1.2 磁盘的逻辑抽象结构 2. 理解文件系统2.1 前言2.2 文件系统2.3 文件的新建和删除2.4 文件的查找2.5 理解软硬链接 3. 动态库和静态库3.1 生成静态库3.2 生成动态库3.3 动态库加载 实际上,大部分文件都不是被打开的(当…

pikachu靶场通关全流程

目录 暴力破解: 1.基于表单的暴力破解: 2.验证码绕过(on server): 3.验证码绕过(on client): token防爆破: XSS: 1.反射型xss(get): 2.反射性xss(post): 3.存储型xss&#…

一道初中一年级几何题解析

来看一个初中一年级的几何题目: 直接看第三问。 拿到题后直接解的话就是在 BC 上截取 BP 等于 CE,就直接得出 PBD 和 ECD 全等,加上角 EDF 等于 45 度,就能得到角 EDF 等于角 PDF,于是 PDF 与 EDF 全等,…

自定义组件——ABManager(AB包管理器)

需求描述 在Unity3D引擎中,AB包作为常用的游戏资源存储格式之一。而对于资源管理我们就不得不谈到集中管理的优势了,通过统一的接口加载和卸载AB包及其中的资源将进一步提升我们的编程效率。本文将围绕这个需求进行尝试。 功能描述 1. AB包的加载包括同…

代码随想录算法训练营第五十五 | ● 583. 两个字符串的删除操作 ● 72. 编辑距离

583. 两个字符串的删除操作 https://programmercarl.com/0583.%E4%B8%A4%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%88%A0%E9%99%A4%E6%93%8D%E4%BD%9C.html class Solution { public:int minDistance(string word1, string word2) {vector<vector<int>> d…

遇到的状态308问题

前端用的vue.config.js做的代理,请求后端的地址https://n6118lr7-10010.usw3.devtunnels.ms 在请求的时候会308 是因为本地是http而请求地址是https 前端代理允许https接口代理即可