Article title on dark background

每一次线上活动都会留下痕迹;有时,这些痕迹可能威胁你的安全,或妨碍网页抓取。代理能帮助你规避反爬系统的检测,同时确保任务顺利执行。本文将介绍如何在 C# 和 .NET 中配置 DataImpulse 代理,避免触发速率限制,也减少被恶意行为者利用的风险。

开始使用

首先,请确保设备上已安装以下必要工具:

  • Visual Studio Code(Visual Studio 2022或任何其他支持.NET的集成开发环境也可以)
  • .NET 8
  • HtmlAgilityPack(本教程使用版本1.6.11)

本教程会用到代理,因此你需要注册 DataImpulse 账户并选择适合自己需求的套餐。我们提供了分步指南,说明如何完成设置。

本教程以抓取我们自己的网站 DataImpulse.com为例。不过,你可以根据实际任务轻松调整代码,抓取所需的任何数据源。当然,请务必遵守目标网站的服务条款。

创建HTTP客户端

首先需要创建一个 HTTP 客户端,让流量经由指定的代理服务器转发。这是一个简单的控制台应用程序,会向指定 URL 发送请求并获取响应,整个过程均通过代理服务器完成。你可以复制下面的代码片段。 


using System.Net;

class HttpClientApp
{
    public static void Main(string[] args)
    {
        DownloadPageAsync().Wait();
    }

    private static async Task DownloadPageAsync()
    {
        string page = "https://api.ipify.org/"; // Example API to get the public IP address

        // Configure proxy
        var proxy = new WebProxy("gw.dataimpulse.com:823")
        {
            UseDefaultCredentials = false,
            Credentials = new NetworkCredential("your login", "your password")
        };

        // Set up HTTP client handler with proxy
        var httpClientHandler = new HttpClientHandler
        {
            Proxy = proxy,
            UseProxy = true
        };

        using (var client = new HttpClient(handler: httpClientHandler, disposeHandler: true))
        {
            try
            {
                // Send the HTTP GET request
                var response = await client.GetAsync(page);

                // Check if the response is successful
                response.EnsureSuccessStatusCode();

                // Get the content of the response
                string result = await response.Content.ReadAsStringAsync();
                Console.WriteLine("Response received: ");
                Console.WriteLine(result);
                Console.WriteLine("Press any key to exit.");
                Console.ReadLine(); // Keep the console open to display the result
            }
            catch (HttpRequestException e)
            {
                Console.WriteLine($"Request error: {e.Message}");
                Console.WriteLine("Press any key to exit.");
                Console.ReadLine(); // Keep the console open to display the result
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Unexpected error: {ex.Message}");
                Console.WriteLine("Press any key to exit.");
                Console.ReadLine(); // Keep the console open to display the result
            }
        }
    }
}

      
        

      

要运行此应用以及后续应用,请在应用根目录下打开终端并输入以下命令。


dotnet run --project NameOfProject
      
        

      

输出应如下所示:

实现代理轮换

仅让流量经由代理服务器转发还不够。为降低触发限制的风险,你需要为每个请求使用新的 IP 地址。因此,下一步是构建一个代理轮换器,从代理池中随机选择一个地址。


using System.Net;

class ProxyRotator
{
    // List of proxies to rotate through
    private static List proxies = new List
    {
        new WebProxy("http://gw.dataimpulse.com:10000"),
        new WebProxy("http://gw.dataimpulse.com:10001"),
        new WebProxy("http://gw.dataimpulse.com:10002")
    };

    public static void Main(string[] args)
    {
        MakeRequestsWithRotation().Wait();
    }

    private static async Task MakeRequestsWithRotation()
    {
        // Example URLs to request
        string url = "https://api.ipify.org/";

        for (int i = 0; i < proxies.Count; i++)
        {
            // Send request using each proxy
            Console.WriteLine($"Using proxy: {proxies[i].Address}");
            try
            {
                var response = await SendRequestWithProxy(url, proxies[i]);
                if (response.IsSuccessStatusCode)
                {
                    Console.WriteLine($"Request succeeded with proxy {proxies[i].Address}");
                    string responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"IP address from API website: {responseBody}");  // Print or process the response as needed
                }
                else
                {
                    Console.WriteLine($"Request failed with proxy {proxies[i].Address}, Status Code: {response.StatusCode}");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Exception with proxy {proxies[i].Address}: {ex.Message}");
            }
        }
    }

    // Function to send request using a specific proxy
    private static async Task SendRequestWithProxy(string url, WebProxy proxy)
    {
        HttpClientHandler handler = new HttpClientHandler
        {
            Proxy = proxy,
            UseProxy = true
        };

        using (HttpClient client = new HttpClient(handler))
        {
            return await client.GetAsync(url);
        }
    }
}

      
        

      

在上面的示例中,我们准备了一个用于轮换的代理列表(本例中包含 3 个代理),并通过http://api.ipify.org/ URL 检查轮换后的 IP 地址。结果应如下所示:

构建代理检查器

为确保代理正常工作,我们需要创建一个代理检查器。它会通过代理服务器发送 HTTP 请求,并判断代理是否可用。这里使用 dataimpulse.com,但也可以换成其他链接。


using System.Net;

class ProxyChecker
{
    // Entry point renamed to avoid conflict
    public static void Main(string[] args)
    {
        string proxyAddress = "gw.dataimpulse.com"; // Replace with your proxy address
        // Replace with your proxy ports
        var proxyPortStart = 10000; 
        var proxyPortEnd = 10100;

        var tasks = new List();
        for (var proxyPort = proxyPortStart; proxyPort < proxyPortEnd; proxyPort++)
        {
            tasks.Add(CheckProxy(proxyAddress, proxyPort));
        }

        Task.WaitAll(tasks.ToArray());
    }

    public static async Task CheckProxy(string proxyAddress, int proxyPort)
    {
        var proxy = new WebProxy(proxyAddress, proxyPort)
        {
            // Uncomment and modify if the proxy requires credentials
            Credentials = new NetworkCredential("your login", "your password"),
            BypassProxyOnLocal = false
        };

        var httpClientHandler = new HttpClientHandler
        {
            Proxy = proxy,
            UseProxy = true
        };

        using (var client = new HttpClient(httpClientHandler))
        {
            try
            {
                client.Timeout = TimeSpan.FromSeconds(10); // Set a timeout
                var response = await client.GetAsync("https://api.ipify.org/"); // You can use any URL for testing
                if (response.IsSuccessStatusCode)
                {
                    Console.WriteLine("Proxy is working: " + proxyAddress + ":" + proxyPort);
                }
                else
                {
                    Console.WriteLine("Proxy is not working (Invalid response): " + proxyAddress + ":" + proxyPort);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Proxy is not working (Exception): " + proxyAddress + ":" + proxyPort + " - " + ex.Message);
            }
        }
    }
}

      
        

      

在这里,你需要指定主机名、端口和凭据。你可以在 DI 控制面板中相应套餐的标签页找到这些信息。还需要设置以秒为单位的超时时间。

下面是结果示例:

抓取数据

项目的核心是一个网页抓取器。它会发送 HTTP 请求,并从 DataImpulse 首页抓取 HTML 数据。


using System.Net;
using HtmlAgilityPack;

class WebScraper
{
    public static void Main(string[] args)
    {
        Scrape().Wait();
    }

    private static async Task Scrape()
    {
        // Define the proxy details
        string proxyAddress = "http://gw.dataimpulse.com:823"; // Replace with your proxy address
        string proxyUsername = "your login"; // Replace with your proxy username (if needed)
        string proxyPassword = "your password"; // Replace with your proxy password (if needed)

        // Create a Proxy Handler
        var httpClientHandler = new HttpClientHandler
        {
            Proxy = new WebProxy(proxyAddress)
            {
                Credentials = new NetworkCredential(proxyUsername, proxyPassword)
            },
            UseProxy = true
        };

        // Create an HttpClient using the handler with the proxy
        using (var client = new HttpClient(httpClientHandler))
        {
            // Define the target URL to scrape
            string url = "https://dataimpulse.com/";
            var baseUri = new Uri(url);

            try
            {
                // Send GET request
                var response = await client.GetAsync(url);

                // Use the new code snippet here
                if (response.IsSuccessStatusCode)
                {
                    var content = await response.Content.ReadAsStringAsync();

                    // Load the HTML content into an HtmlDocument
                    HtmlDocument doc = new();
                    doc.LoadHtml(content);

                    // Use XPath to find all  tags that are direct children of 
  • ,

    , or var nodes = doc.DocumentNode.SelectNodes("//li/a[@href] | //p/a[@href] | //td/a[@href]"); if (nodes != null) { foreach (var node in nodes) { string hrefValue = node.GetAttributeValue("href", string.Empty); string title = node.InnerText; // This gets the text content of the tag, which is usually the title var fullUri = new Uri(baseUri, hrefValue); Console.WriteLine($"Title: {title}, Link: {fullUri.AbsoluteUri}"); // You can process each title and link as required } } else { Console.WriteLine("No matching nodes found."); } } else { Console.WriteLine($"Failed to scrape. Status code: {response.StatusCode}"); } } catch (Exception ex) { Console.WriteLine($"An error occurred: {ex.Message}"); } } } }

  • 不过,你可以按需修改代码,以获取所需的数据。 

    为什么选择DataImpulse?

    在网页抓取项目中,你可能会考虑使用公共代理,因为看起来能节省成本。然而,免费代理存在许多风险,包括连接失败、速度缓慢和个人数据泄露,因为你无法知道这些服务器由谁运营。如果想进一步了解应避免免费代理的原因,请参阅以下文章:为什么不应该使用假IP和免费代理以及从低速到安全威胁:为什么你应该避免免费代理。因此,你应选择可信赖的服务提供商。DataImpulse 提供合法获取且未涉及恶意活动的 IP 地址,并提供价格实惠的套餐。例如,住宅代理每 1 GB 仅需 $1。我们采用按量付费的定价模式,因此无需担心流量过期。点击屏幕右上角的”立即试用“按钮,或发送邮件至[email protected]。 

    Share article: