【问题标题】:What is the fastest way for checking a big proxy list on a specific web site?检查特定网站上的大型代理列表的最快方法是什么?
【发布时间】:2012-09-03 14:23:29
【问题描述】:

我有一大堆代理服务器(txt 文件,格式 = ip:port 在每一行),并编写了下面的代码来检查它们:

    public static void MyChecker()
    {
        string[] lines = File.ReadAllLines(txtProxyListPath.Text);
        List<string> list_lines = new List<string>(lines);
        List<string> list_lines_RemovedDup = new List<string>();
        HashSet<string> HS = new HashSet<string>();
        int Duplicate_Count = 0;
        int badProxy = 0;
        int CheckedCount = 0;

        foreach (string line in list_lines)
        {
            string[] line_char = line.Split(':');
            string ip = line_char[0];
            string port = line_char[1];
            if (CanPing(ip))
            {
                if (SoketConnect(ip, port))
                {
                    if (CheckProxy(ip, port))
                    {
                        string ipAndport = ip + ":" + port;
                        if (HS.Add(ipAndport))
                        {
                            list_lines_RemovedDup.Add(ipAndport);
                            CheckedCount++;
                        }
                        else
                        {
                            Duplicate_Count++;
                            CheckedCount++;
                        }
                    }
                    else
                    {
                        badProxy++;
                        CheckedCount++;
                    }
                }
                else
                {
                    badProxy++;
                    CheckedCount++;
                }
            }
            else
            {
                badProxy++;
                CheckedCount++;
            }
    }

    public static bool CanPing(string ip)
    {
        Ping ping = new Ping();

        try
        {
            PingReply reply = ping.Send(ip, 2000);
            if (reply == null)
                return false;

            return (reply.Status == IPStatus.Success);
        }
        catch (PingException Ex)
        {
            return false;
        }
    }

    public static bool SoketConnect(string ip, string port)
    {
        var is_success = false;
        try
        {
            var connsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            connsock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 200);
            System.Threading.Thread.Sleep(500);
            var hip = IPAddress.Parse(ip);
            var ipep = new IPEndPoint(hip, int.Parse(port));
            connsock.Connect(ipep);
            if (connsock.Connected)
            {
                is_success = true;
            }
            connsock.Close();
        }
        catch (Exception)
        {
            is_success = false;
        }
        return is_success;
    }

    public static bool CheckProxy(string ip, string port)
    {
        try
        {
            WebClient WC = new WebClient();
            WC.Proxy = new WebProxy(ip, int.Parse(port));
            WC.DownloadString("http://SpecificWebSite.com");
            return true;
        }
        catch (Exception)
        {
            return false;
        }
    }

但我认为我应该重写这些代码,因为它们非常慢。
我在这些方面有严重的延误:
WC.DownloadString("http://SpecificWebSite.com");

PingReply reply = ping.Send(ip, 2000);
这不适合大名单。
我是按照正确的方向编写这些代码还是应该更改它们(哪些部分)?
我怎样才能优化它们?

提前致谢

【问题讨论】:

    标签: c# .net-4.0 proxy windows-applications


    【解决方案1】:

    有很多事情可以改进。

    • 半秒内不要让线程休眠。
    • 放弃 ping 检查(因为代理可能位于防火墙后面并且 不响应 ping,但仍在工作)
    • 将 DownloadString 替换为仅获取 HEAD 的 HttpWebRequest。
    • 将 HttpWebRequest 的超时设置为低于 默认(无需等待那么长时间。如果代理在 10-20 秒然后你可能不想使用它)。
    • 将大列表拆分为较小的列表并同时处理它们 时间。

    仅这些就可以大大加快您的流程。

    根据要求,这里是一个如何使用 HttpWebRequests 的示例

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Proxy = null;   // set proxy here
    request.Timeout = 10000; 
    request.Method = "HEAD";
    
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        Console.WriteLine(response.StatusCode);
    }
    

    【讨论】:

    • 我想使用Parallel.ForEach 比将列表拆分成更小的列表更合适。
    • 如果您使用的是 .NET 4 及更高版本(您是),那么可以。
    • 另外,你的 MyChecker() 有几个参数都返回 false,将它们组合在一起。例如: if (!SoketConnect(ip, port) || !CanPing(ip)) { badProxy++;检查计数++; }。它不应该对性能产生任何影响,但它应该使它更具可读性,而不必使用所有这些括号。
    • @CooLMinE 感谢您的关注和回答。请给我一个 HttpWebRequest 的例子...
    【解决方案2】:

    我可能会这样做:

    public static bool TestProxy(string ipAddress, int port, out string errorMsg, out double connectionSeconds) {
      Stopwatch stopWatch = new Stopwatch();
      errorMsg = "";
      connectionSeconds = -1;
    
      try {
        stopWatch.Start();
        var client = new RestClient("https://webapi.theproxisright.com/");
        client.Proxy = new WebProxy(ipAddress, port);
    
        var request = new RestRequest("api/ip", Method.GET);
        request.Timeout = 10000;
        request.RequestFormat = DataFormat.Json;
    
        var response = client.Execute(request);
        if (response.ErrorException != null) {
          throw response.ErrorException;
        }
        return (response.Content == ipAddress);
      } catch (Exception ex) {
        errorMsg = ex.Message;
        return false;
      } finally {
        stopWatch.Stop();
        connectionSeconds = stopWatch.Elapsed.TotalSeconds;
      }
    }
    

    使用类似 WhatIsMyIP 的 REST 服务(我使用来自 https://TheProxIsRight.com 的服务)。

    然后如上所述,我可能会尝试将其并行化为:

      Task.Factory.StartNew(() => {
        try {
          string errorMsg;
          double connectionTime;
          var success = TestProxy("1.2.3.4",3128, out errorMsg, out connectionTime);
    
          //Log Result
        } catch (Exception ex) {
          //Log Error
        }
      });
    

    注意,也可以使用上述站点上的 REST API 来查询工作代理: https://theproxisright.com/#apidemo

    (披露,我在上述网站工作)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-25
      • 2010-11-05
      • 2014-01-28
      • 2019-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-19
      相关资源
      最近更新 更多