2

C#攻克反爬虫;代理IP爬取

 8 months ago
source link: https://blog.51cto.com/u_16022798/8924937
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

C#攻克反爬虫;代理IP爬取

精选 原创

系阿文呐 2023-12-21 16:05:19 ©著作权

文章标签 IP html 代理服务器 文章分类 PyTorch 人工智能 阅读数190

C#攻克反爬虫;代理IP爬取_代理服务器

随着互联网的发展,反爬虫技术也越来越成熟,很多网站都对爬取行为进行限制,例如限制访问频率、封禁IP等。为了规避这些限制,爬虫程序可以使用代理IP进行爬取。本文将介绍如何使用C#实现代理IP的爬取,并且解决一些常见的问题。

一、什么是代理IP

代理IP是一种用于隐藏真实IP地址的网络技术。通过使用代理服务器,我们可以将请求发送到代理服务器上,再由代理服务器代为发送请求,从而隐藏真实IP地址。代理服务器充当了客户端与目标服务器之间的中间人。在爬虫中,我们可以通过使用代理IP来规避目标网站的反爬虫策略。

二、代理IP的获取

  1. 免费代理IP网站

免费代理IP网站是最常见的一种获取代理IP的方法。这些网站通常会提供公开的代理IP地址供开发者使用。通过爬取这些网站的代理IP列表,我们可以获取大量的代理IP地址。

  1. 第三方API

除了免费代理IP网站外,还有一些第三方提供的代理IP API,比如站大爷代理ip、蝶鸟ip等。这些API通常需要付费使用,但提供的代理IP质量更高、稳定性更好。

三、C#实现代理IP爬取

使用C#实现代理IP爬取可以借助HtmlAgilityPack和HttpClient两个库。

  1. 安装HtmlAgilityPack和HttpClient

使用NuGet包管理器,通过搜索"HtmlAgilityPack"和"HttpClient",安装这两个库。

  1. 获取代理IP

以下代码实现了从免费代理IP网站获取代理IP的功能:

using System;
using System.Net.Http;
using HtmlAgilityPack;

class Program
{
    static async Task Main(string[] args)
    {
        var httpClient = new HttpClient();
        var html = await httpClient.GetStringAsync("https://www.freeip.top/?page=1");

        var htmlDocument = new HtmlDocument();
        htmlDocument.LoadHtml(html);

        var ipNodes = htmlDocument.DocumentNode.SelectNodes("//tbody/tr/td[1]");
        var portNodes = htmlDocument.DocumentNode.SelectNodes("//tbody/tr/td[2]");

        foreach (var ipNode in ipNodes)
        {
            Console.WriteLine(ipNode.InnerText);
        }

        foreach (var portNode in portNodes)
        {
            Console.WriteLine(portNode.InnerText);
        }
    }
}

以上代码使用HttpClient库发送GET请求获取代理IP网站的HTML代码,然后使用HtmlAgilityPack库将HTML代码解析成DOM树,然后通过XPath选择器提取出IP地址和端口号。

  1. 使用代理IP发送请求

获取到代理IP后,我们可以使用HttpClient库进行访问目标网站。以下代码演示了如何使用代理IP发送GET请求:

static async Task Main(string[] args)
{
    var httpClientHandler = new HttpClientHandler()
    {
        UseProxy = true,
        Proxy = new WebProxy("127.0.0.1", 8888) // 代理IP地址和端口号
    };

    var httpClient = new HttpClient(httpClientHandler);
    var html = await httpClient.GetStringAsync("https://www.example.com");

    Console.WriteLine(html);
}

以上代码创建了一个HttpClientHandler对象,设置了代理IP地址和端口号,然后将该对象传递给HttpClient对象。接下来,使用HttpClient对象发送GET请求获取目标网站的内容。

四、常见问题及解决方案

  1. 代理IP的可用性

免费代理IP网站提供的代理IP质量参差不齐,有些代理IP可能已经失效。为了保证代理IP的可用性,我们可以使用多线程进行代理IP的检测。以下代码演示了如何使用多线程进行代理IP的检测:

static async Task Main(string[] args)
{
    var httpClient = new HttpClient();
    var html = await httpClient.GetStringAsync("https://www.zdaye.com");

    var htmlDocument = new HtmlDocument();
    htmlDocument.LoadHtml(html);

    var ipNodes = htmlDocument.DocumentNode.SelectNodes("//tbody/tr/td[1]");
    var portNodes = htmlDocument.DocumentNode.SelectNodes("//tbody/tr/td[2]");

    List<Task<bool>> tasks = new List<Task<bool>>();

    foreach (var ipNode in ipNodes)
    {
        var ip = ipNode.InnerText;
        var port = portNodes[ipNodes.IndexOf(ipNode)].InnerText;
        tasks.Add(IsProxyIpValid(httpClient, ip, port));
    }

    await Task.WhenAll(tasks);

    foreach (var task in tasks)
    {
        if (task.Result)
        {
            Console.WriteLine("该代理IP可用");
        }
        else
        {
            Console.WriteLine("该代理IP不可用");
        }
    }
}

static async Task<bool> IsProxyIpValid(HttpClient httpClient, string ip, string port)
{
    try
    {
        var httpClientHandler = new HttpClientHandler()
        {
            UseProxy = true,
            Proxy = new WebProxy(ip, int.Parse(port))
        };

        var httpClient = new HttpClient(httpClientHandler);
        var response = await httpClient.GetAsync("https://www.example.com");

        return response.StatusCode == HttpStatusCode.OK;
    }
    catch
    {
        return false;
    }
}

以上代码使用多线程检测代理IP的可用性,通过向目标网站发起请求,判断响应的状态码是否为200来判断代理IP的有效性。

  1. 频繁更换代理IP

有些网站可能对单个IP地址的请求频率进行限制,因此我们可以使用多个代理IP轮流使用,从而规避频率限制。以下代码演示了如何在爬虫程序中轮流使用代理IP:

static async Task Main(string[] args)
{
    var httpClient = new HttpClient();

    var proxyIps = new List<string>() { "127.0.0.1:8888", "127.0.0.1:8889", "127.0.0.1:8890" };
    var currentProxyIpIndex = 0;

    // 循环使用代理IP发送请求
    for (int i = 0; i < 10; i++)
    {
        var currentProxyIp = proxyIps[currentProxyIpIndex];

        var proxyIp = currentProxyIp.Split(':')[0];
        var proxyPort = currentProxyIp.Split(':')[1];

        var httpClientHandler = new HttpClientHandler()
        {
            UseProxy = true,
            Proxy = new WebProxy(proxyIp, int.Parse(proxyPort))
        };

        var httpClient = new HttpClient(httpClientHandler);
        var html = await httpClient.GetStringAsync("https://www.example.com");

        Console.WriteLine(html);

        currentProxyIpIndex = (currentProxyIpIndex + 1) % proxyIps.Count;
    }
}

以上代码使用循环和取模运算符实现了轮流使用代理IP的功能。每次发送请求时,选择下一个代理IP发送请求。这样可以保证每个请求都使用不同的代理IP,提高爬取的效率。

本文介绍了使用C#实现代理IP爬取的方法,并解决了一些常见的问题。在实际的爬虫开发中,代理IP是一个非常有用的工具,可以帮助我们规避反爬虫策略,提高爬取效率。然而,需要注意的是,使用代理IP爬取也可能面临一些挑战,比如代理IP的可用性和频繁更换代理IP等问题,需要我们灵活应对。希望本文对大家理解代理IP爬取有所帮助。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK