C#实现IP代理池调度的示例代码
作者:Csharp 小记
这篇文章主要为大家介绍了C#实现IP代理池调度的相关知识,文中的示例代码讲解详细,具有一定的参考与学习价值,感兴趣的小伙伴可以了解一下
前言
稍微介绍下这个代码的用途,在做某些功能的时候,我们可能会用到IP代理,购买IP的时候也是可以选择长期高质量IP或者短失效但量大的IP,这个主要根据用途来购买;这里就是基于大量短失效IP做的一个IP调度,尽可能保证IP能够物尽其用。
实现
1.首先定义一个IPPool类,然后在构造函数中传入以下参数
public class IPPool { readonly string _ipUrl, _checkUrl; readonly int _saveCount; readonly bool _loopUse; public ConcurrentQueue<string> IPQueue = new ConcurrentQueue<string>(); /// <summary> /// 代理IP池 /// </summary> /// <param name="ipUrl">代理IP的获取网址</param> /// <param name="checkUrl">检查IP可用性的网址</param> /// <param name="saveCount">IP池的存储量</param> /// <param name="loopUse">是否循环使用</param> public IPPool(string ipUrl, string checkUrl, int saveCount, bool loopUse=true) { _ipUrl = ipUrl; _checkUrl = checkUrl; _saveCount = saveCount; _loopUse = loopUse; }
2.解析网页上的IP地址,这里使用虚方法,以方便可以重写解析方法,应对不同的数据类型
/// <summary> /// 解析网址IP /// </summary> /// <returns></returns> protected virtual List<string> Parse() { List<string> list = new List<string>(); try { HttpClient httpClient = new HttpClient(); httpClient.Timeout = new TimeSpan(0, 0, 10); var result = httpClient.GetStringAsync(_ipUrl).Result; JObject jobj = JObject.Parse(result); if (jobj["code"].ToString() == "1") { JArray jarr = (JArray)jobj["data"]; foreach (var item in jarr) { string ip = item["ip"].ToString() + ":" + item["port"].ToString(); list.Add(ip); } } } catch { } return list; }
3.检查IP可用性,这里可以使用你需要访问的网址或者百度进行Get,保证可以访问到即可,同样使用虚方法定义
/// <summary> /// 检查IP可用性 /// </summary> /// <param name="ip"></param> /// <returns></returns> protected virtual bool Check(string ip) { HttpClient httpClient = new HttpClient(); httpClient.Timeout = new TimeSpan(0, 0, 10); bool result = httpClient.GetAsync(_checkUrl).Result.StatusCode == HttpStatusCode.OK; return result; }
4.开始获取,使用定时器获取,同样因为有设置队列的最大值,所以只有当低于这个阈值时才会进行补充,防止IP浪费的同时保证IP充足够用
/// <summary> /// 开始获取 /// </summary> /// <param name="interval">获取间隔</param> public virtual void Start(double interval) { System.Timers.Timer timer = new System.Timers.Timer(interval); timer.Elapsed += (s, e) => { if (IPQueue.Count < _saveCount) { List<string> list = Parse(); foreach (var ip in list) { IPQueue.Enqueue(ip); } } }; timer.Start(); }
5.获取IP,从队列中获取,如果设置了循环使用的话,不失效可以一直使用,进一步保证IP资源
/// <summary> /// 获取IP /// </summary> /// <returns></returns> public virtual string Get() { string ip = null; while (IPQueue.Count > 0) { IPQueue.TryPeek(out ip); if (!string.IsNullOrEmpty(ip)&&Check(ip)) { if (!_loopUse) { IPQueue.TryDequeue(out ip); } break; } else { IPQueue.TryDequeue(out string result); } } return ip; } }
6.为方便测试,我们自定义一个类继承IPPool,然后重写Parse以及Check方法
public IPHelper(string ipUrl, string checkUrl, int saveCount, bool loopUse = true) : base(ipUrl, checkUrl, saveCount,loopUse) { } protected override List<string> Parse() { List<string> list = new List<string>(); list.Add(DateTime.Now.Ticks.ToString()); return list; } protected override bool Check(string ip) { return true; }
7.最后调用下看看效果
private async void button1_Click(object sender, EventArgs e) { listBox1.Items.Clear(); IPHelper iPHelper = new IPHelper("", "", 10,false); iPHelper.Start(200); for (int i = 0; i < 5; i++) { string ip = iPHelper.Get(); if (ip != null) { listBox1.Items.Add(ip); } await Task.Delay(500); } } private async void button2_Click(object sender, EventArgs e) { listBox1.Items.Clear(); IPHelper iPHelper = new IPHelper("", "", 10); iPHelper.Start(200); for (int i = 0; i < 5; i++) { string ip = iPHelper.Get(); if (ip != null) { listBox1.Items.Add(ip); } await Task.Delay(500); } }
实现效果
到此这篇关于C#实现IP代理池调度的示例代码的文章就介绍到这了,更多相关C# IP代理池调度内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!