一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C# - c#批量抓取免費代理并且驗證有效性的實戰教程

c#批量抓取免費代理并且驗證有效性的實戰教程

2022-02-25 14:28張林-布萊恩特 C#

突破反爬蟲限制的方法之一就是多用幾個代理IP,下面這篇文章主要給大家介紹了關于利用c#批量抓取免費代理并且驗證有效性的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下

前言

之前看到某公司的官網的文章的瀏覽量刷新一次網頁就會增加一次,給人的感覺不太好,一個公司的官網給人如此直白的漏洞,我批量發起請求的時候發現頁面打開都報錯,100多人的公司的官網文章刷新一次你給我看這個,這公司以前來過我們學校宣傳招人+在園子里搜招聘的時候發現居然以前招xamarin,挺好奇的,所以就關注過。好吧不說這些了,只是扯扯蛋而已,回歸主題,我想說的是csdn的文章可以通過設置代理ip刷新文章的瀏覽量,所以首先要做的就是這篇文章的主題“使用c#驗證代理ip有效性”。

當然代理ip來源肯定是免費,所以嘛效率一般,從一些免費的代理ip的網頁抓取的代理ip并不一定都是有用的,所以需要我們對我們抓取的代理ip進行驗證,代理ip的有效時間也是有限,從10幾秒到1個小時不限,大多數時間非常短,所以比如說,我們1分鐘需要100個代理ip,那就1分鐘獲取一次,每次獲取100個(這里是理想狀態下的,抓取的代理ip都是有效的),原則上來說抓取下來后應該立即馬上被使用。

當然這篇文章比較基礎,一直覺得爬蟲比較有趣,其實我在爬蟲方面也是個小白,只是做一個簡單的記錄,如果有什么錯誤的地方,希望能提出建議。針對下面幾個問題,我們就可以完成如何驗證代理ip有效性的檢測了。

1.從哪些網頁上可以抓取免費的代理ip?

http://www.xicidaili.com

http://www.ip3366.net

http://www.66ip.cn

百度一下“免費代理ip”挺多的。

2.代理ip穩定嗎?有什么作用?

這種免費的代理ip時效性和有效性都不強,上面這三個免費的代理網站,時效性大概在十幾秒到1個小時不等,一般需要自己處理驗證后使用,提高命中率。可適用于隱藏網頁ip(有些網站還不準使用代理ip,比如豆瓣,其實挺尷尬的,內容這么貴嗎),一般常用于空間留言、刷網站流量、網賺任務、批量注冊賬號等,只要沒有其他限制,需要頻繁更換ip都可以使用。

3.ping通ip就是有效的嗎?如何驗證代理是否有效

好吧,這有點廢話,進行端口測試才是最有效的,能ping通并不代表代理有效,不能平通也不一定代理不可用。可以使用httpwebrequest,也可以使用scoket,當然httpwebrequest比socket連接代理ip、port要慢。

4.一次提取多少代理合適?

代理ip時效性不強、并且有效性也不高,所以只能從一些代理ip的網站上批量定時去獲取,有的代理在一分鐘內使用是有限制的,所以說限制比較多。

5.http代理和https代理有什么區別?

需要訪問https的網站就需要使用https代理了,比如百度,需要訪問http的代理,可以使用http。這個并不是100%的。

檢測代理ip有效性步驟如下:

1.使用httpwebrequest、httpwebresponse請求代理ip的網頁,獲取包含代理的網頁內容

2.使用htmlagilitypack或者正則表達式對抓取的內容進行截取,保存到代理集合

3.拿到代理集合,多線程發起http請求,比如訪問百度,是否成功,成功則存到redis里面。

效果圖如下:

c#批量抓取免費代理并且驗證有效性的實戰教程

使用httpwebrequest發起請求

request.cs如下,主要就是兩個方法,一個方法是驗證代理ip是否有效,設置httpwebrequest的proxy屬性,請求百度,看到有些文章大多數會獲取響應的內容,如果內容符合請求的網址則證明代理喲有效,實際上根據httpstatuscode 200就可以判斷是否驗證有效。

【注意】建的是控制臺程序,使用了異步,所以還是建.net core吧,c#語言的版本7.1。c#如何在控制臺程序中使用異步

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
public class request
 {
 /// <summary>
 /// 驗證代理ip有效性
 /// </summary>
 /// <param name="proxyip">代理ip</param>
 /// <param name="proxyport">代理ip 端口</param>
 /// <param name="timeout">詳情超時</param>
 /// <param name="url">請求的地址</param>
 /// <param name="success">成功的回調</param>
 /// <param name="fail">失敗的回調</param>
 /// <returns></returns>
 public static async system.threading.tasks.task getasync(string proxyip,int proxyport, int timeout,string url, action success, action<string> fail)
 {
  system.gc.collect();
  httpwebrequest request = null;
  httpwebresponse response = null;
  try
  {
  request = (httpwebrequest)webrequest.create(url);
  //httpwebrequest request = httpwebrequest.createhttp(url);
  request.timeout =timeout;
  request.keepalive = false;
  request.proxy = new webproxy(proxyip,proxyport);
  response = await request.getresponseasync() as httpwebresponse;
  if (response.statuscode == httpstatuscode.ok)
  {
   success();
  }
  else
  {
   fail(response.statuscode+":"+response.statusdescription);
  }
  }
  catch (exception ex)
  {
  fail("請求異常"+ex.message.tostring());
  }
  finally
  {
  if (request != null)
  {
   request.abort();
   request = null;
  }
  if (response != null)
  {
   response.close();
  }
  }
 }
 
 /// <summary>
 /// 發起http請求
 /// </summary>
 /// <param name="url"></param>
 /// <param name="success">成功的回調</param>
 /// <param name="fail">失敗的回調</param>
 public static void get(string url,action<string> success,action<string> fail)
 {
  streamreader reader = null;
  stream stream = null;
  webrequest request = null;
  httpwebresponse response = null;
  try
  {
  request = webrequest.create(url);
  request.timeout = 2000;
  response = (httpwebresponse)request.getresponse();
  if (response.statuscode == httpstatuscode.ok)
  {
   stream = response.getresponsestream();
   reader = new streamreader(stream);
   string result = reader.readtoend();
   success(result);
  }
  else
  {
   fail(response.statuscode+":"+response.statusdescription);
  }
  }
  catch (exception ex)
  {
  fail(ex.tostring());
  }
  finally
  {
  if (reader != null)
   reader.close();
  if (stream != null)
   stream.close();
  if(response!=null)
   response.close();
  if(request!=null)
   request.abort();
  }
 }
 }

抓取免費代理,并檢查是否有效

proxyiphelper.cs 中主要有四個方法,檢查ip是否可用checkproxyipasync、抓取xicidaili.com的代理getxicidailiproxy、抓取ip3366.net的代理getip3366proxy、抓取66ip.cn的代理getip3366proxy。如果想多抓取幾個網站可以多寫幾個。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
public class proxyiphelper
 {
  private static string address_xicidaili = "http://www.xicidaili.com/wn/{0}";
  private static string address_66ip = "http://www.66ip.cn/nmtq.php?getnum=20&isp=0&anonymoustype=0&start=&ports=&export=&ipaddress=&area=1&proxytype=1&api=66ip";
  private static string address_ip3366 = "http://www.ip3366.net/?stype=1&page={0}";
  /// <summary>
  /// 檢查代理ip是否可用
  /// </summary>
  /// <param name="ipaddress">ip</param>
  /// <param name="success">成功的回調</param>
  /// <param name="fail">失敗的回調</param>
  /// <returns></returns>
  public static async task checkproxyipasync(string ipaddress, action success, action<string> fail)
  {
   int index = ipaddress.indexof(":");
   string proxyip = ipaddress.substring(0, index);
   int proxyport = int.parse(ipaddress.substring(index + 1));
   await request.getasync(proxyip, proxyport, 3000, "https://www.baidu.com/", () =>
   {
    success();
   }, (error) =>
   {
    fail(error);
   });
  }
  /// <summary>
  /// 從xicidaili.com網頁上去獲取代理ip,可以分頁
  /// </summary>
  /// <param name="page"></param>
  /// <returns></returns>
  public static list<string> getxicidailiproxy(int page)
  {
   list<string> list = new list<string>();
   for (int p = 1; p <= page; p++)
   {
    string url = string.format(address_xicidaili, p);
    request.get(url,(doctext)=> {
     if (!string.isnullorwhitespace(doctext))
     {
      htmldocument doc = new htmldocument();
      doc.loadhtml(doctext);
      var trnodes = doc.documentnode.selectnodes("//table[@id='ip_list']")[0].selectnodes("./tr");
      if (trnodes != null && trnodes.count > 0)
      {
       for (int i = 1; i < trnodes.count; i++)
       {
        var tds = trnodes[i].selectnodes("./td");
        string ipaddress = tds[1].innertext + ":" + int.parse(tds[2].innertext); ;
        list.add(ipaddress);
       }
      }
     }
    },(error)=> {
     console.writeline(error);
    });
   }
   return list;
   }
  /// <summary>
  /// 從ip3366.net網頁上去獲取代理ip,可以分頁
  /// </summary>
  /// <param name="page"></param>
  /// <returns></returns>
  public static list<string> getip3366proxy(int page)
  {
   list<string> list = new list<string>();
   for (int p = 1; p <= page; p++)
   {
    string url = string.format(address_ip3366, p);
    request.get(url, (doctext) => {
     if (!string.isnullorwhitespace(doctext))
     {
      htmldocument doc = new htmldocument();
      doc.loadhtml(doctext);
      var trnodes1 = doc.documentnode.selectnodes("//table")[0];
      var trnodes2 = doc.documentnode.selectnodes("//table")[0].selectsinglenode("//tbody");
      var trnodes = doc.documentnode.selectnodes("//table")[0].selectsinglenode("//tbody").selectnodes("./tr");
      if (trnodes != null && trnodes.count > 0)
      {
       for (int i = 1; i < trnodes.count; i++)
       {
        var tds = trnodes[i].selectnodes("./td");
        if (tds[3].innerhtml == "https")
        {
         string ipaddress = tds[0].innertext + ":" + int.parse(tds[1].innertext); ;
         list.add(ipaddress);
        }
       }
      }
     }
    }, (error) => {
     console.writeline(error);
    });
   }
   return list;
   }
  /// <summary>
  /// 從66ip.cn中去獲取,不需要分頁
  /// </summary>
  /// <returns></returns>
  public static list<string> get66ipproxy()
  {
   list<string> list = new list<string>();
   request.get(address_66ip,
   (doctext)=> {
    int count = 0;
    if (string.isnullorwhitespace(doctext) == false)
    {
     string regex = "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\:\\d{1,5}";
     match mstr = regex.match(doctext, regex);
     while (mstr.success && count < 20)
     {
      string tempip = mstr.groups[0].value;
      list.add(tempip);
      mstr = mstr.nextmatch();
      count++;
     }
    }
   },
   (error)=> {
    console.writeline(error);
   });
   return list;
  }
 }

使用timer定時抓取,并檢查,成功則保存到redis

c#有三種定時器,這里定時器是使用system.threading命名空間, 這個timer會開啟新的線程,抓取三個網頁定義了三個timer對象。每一次抓取都會保存上一次抓取的集合,檢查前,會進行對比,取出新的集合也就是沒有重復的那部分。有效性的ip比較低,這里沒有做統計,如果代碼再優化一下,可以做一下統計,看看程序的主入口吧,最終的實現如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
class program
 {
  static bool timer_ip3366_iscompleted = true;
  static bool timer_xicidaili_iscompleted = true;
  static bool timer_66ip_iscompleted = true;
  static timer timer_ip3366, timer_xicidaili, timer_66ip;
  private static list<string> lastlistip3366,lastlist66ip,lastlistxicidaili;//保存上一次抓取的代理,與下一次進行對比,取新的集合進行檢查篩選
  static async task main(string[] args)
  {
   system.net.servicepointmanager.defaultconnectionlimit = 2000;
   console.writeline("hellow proxyip");
   console.readline();
   lastlist66ip = new list<string>();
   lastlistip3366 = new list<string>();
   lastlistxicidaili = new list<string>();
   timer_ip3366 = new timer(async (state) =>
   {
    await timerip3366async();
   }, "processing timer_ip3366 event", 0,1000*30);
   timer_xicidaili = new timer(async (state) =>
   {
    await timerxicidailiasync();
   }, "processing timer_xicidaili event", 0, 1000 * 60);
   timer_66ip = new timer(async (state) =>
   {
    await timer66ipasync();
   }, "processing timer_66ip event", 0, 1000*30);
   
   console.readline();
  }
 
 
 
  private static async task timer66ipasync()
  {
   if (timer_66ip_iscompleted)
   {
    timer_66ip_iscompleted = false;
    list<string> checklist = new list<string>();
    var listproxyip = proxyiphelper.get66ipproxy();
 
    if (listproxyip.count > 0)
    {
     console.foregroundcolor = consolecolor.darkcyan;
     console.writeline("66ip.cn 抓取到" + listproxyip.count + "條記錄,正在對比.........");
     listproxyip.foreach(f =>
     {
      if (!lastlist66ip.contains(f))
      {
       checklist.add(f);
      }
     });
     lastlist66ip = listproxyip;
     if (checklist.count > 0)
     {
      console.foregroundcolor = consolecolor.darkcyan;
      console.writeline("66ip.cn 需要檢查" + checklist.count + "條記錄,正在進行檢測是否有效..........");
      for (int i = 0; i < checklist.count; i++)
      {
       string ipaddress = checklist[i];
       await proxyiphelper.checkproxyipasync(ipaddress, () =>
       {
        bool insertsuccess = redishelper.insertset(ipaddress);
        console.foregroundcolor = consolecolor.white;
        console.writeline("66ip.cn");
        if (insertsuccess)
        {
         console.writeline("success" + ipaddress + "任務編號:" + i + "當前任務線程:" + thread.currentthread.managedthreadid);
        }
        console.writeline("重復插入" + ipaddress + "任務編號:" + i + "當前任務線程:" + thread.currentthread.managedthreadid);
       }, (error) =>
       {
        console.foregroundcolor = consolecolor.green;
        console.writeline("66ip.cn");
        console.writeline("error:" + ipaddress + error + "任務編號:" + i + "當前任務線程:" + thread.currentthread.managedthreadid);
       });
      }
      timer_66ip_iscompleted = true;
      console.foregroundcolor = consolecolor.darkcyan;
      console.writeline("66ip.cn" + checklist.count + "條記錄,已經檢測完成,正在進行下一次檢查");
     }
     else
     {
      timer_66ip_iscompleted = true;
      console.foregroundcolor = consolecolor.darkcyan;
      console.writeline("66ip.cn沒有需要檢查的代理ip");
     }
    }
    else
    {
     timer_66ip_iscompleted = true;
     console.foregroundcolor = consolecolor.darkcyan;
     console.writeline("66ip.cn沒有獲取到代理ip");
    }
   }
  }
 
  private static async task timerxicidailiasync()
  {
   if (timer_xicidaili_iscompleted)
   {
    //取出需要檢查的ip地址,第一次100條則checklist就是100條記錄,
    //第二次的100條中只有10是和上一次的不重復,則第二次只需要檢查這10條記錄
    timer_xicidaili_iscompleted = false;
    list<string> checklist = new list<string>();
    var listproxyip = proxyiphelper.getxicidailiproxy(1);
    if (listproxyip.count > 0)
    {
     console.writeline("xicidaili.com 抓取到" + listproxyip.count + "條記錄,正在對比............");
     listproxyip.foreach(f =>
     {
      if (!lastlistxicidaili.contains(f))
      {
       checklist.add(f);
      }
     });
     lastlistxicidaili = listproxyip;
     if (checklist.count > 0)
     {
      console.foregroundcolor = consolecolor.darkcyan;
      console.writeline("xicidaili.com 需要檢查" + checklist.count + "條記錄,正在進行檢測是否有效..........");
      for (int i = 0; i < checklist.count; i++)
      {
       string ipaddress = checklist[i];
       await proxyiphelper.checkproxyipasync(ipaddress, () =>
       {
        bool insertsuccess = redishelper.insertset(ipaddress);
        console.foregroundcolor = consolecolor.white;
        console.writeline("xicidaili.com");
        if (insertsuccess)
        {
         console.writeline("success" + ipaddress + "任務編號:" + i + "當前任務線程:" + thread.currentthread.managedthreadid);
        }
        else
         console.writeline("重復插入" + ipaddress + "任務編號:" + i + "當前任務線程:" + thread.currentthread.managedthreadid);
       }, (error) =>
       {
        console.writeline("xicidaili.com");
        console.foregroundcolor = consolecolor.red;
        console.writeline("error:" + ipaddress + error + "任務編號:" + i + "當前任務線程:" + thread.currentthread.managedthreadid);
       });
      }
      timer_xicidaili_iscompleted = true;
      console.foregroundcolor = consolecolor.darkcyan;
      console.writeline("xicidaili.com" + checklist.count + "條記錄,已經檢測完成,正在進行下一次檢查");
     }
     else
     {
      timer_xicidaili_iscompleted = true;
      console.foregroundcolor = consolecolor.darkcyan;
      console.writeline("xicidaili.com沒有需要檢查的代理ip");
     }
    }
    else
    {
     timer_xicidaili_iscompleted = true;
     console.foregroundcolor = consolecolor.darkcyan;
     console.writeline("xicidaili.com沒有獲取到代理ip");
    }
   }
  }
  private static async task timerip3366async()
  {
   if (timer_ip3366_iscompleted)
   {
    timer_ip3366_iscompleted = false;
    list<string> checklist = new list<string>();
    var listproxyip = proxyiphelper.getip3366proxy(4);
    if (listproxyip.count > 0)
    {
     console.foregroundcolor = consolecolor.darkcyan;
     console.writeline("ip3366.net 抓取到" + listproxyip.count + "條記錄,正在進行檢測是否有效..........");
     listproxyip.foreach(f =>
     {
      if (!lastlistip3366.contains(f))
      {
       checklist.add(f);
      }
     });
     lastlistip3366 = listproxyip;
     if (checklist.count != 0)
     {
      console.foregroundcolor = consolecolor.darkcyan;
      console.writeline("ip3366.net 需要檢查" + checklist.count + "條記錄,正在進行檢測是否有效..........");
      for (int i = 0; i < checklist.count; i++)
      {
       string ipaddress = checklist[i];
       await proxyiphelper.checkproxyipasync(ipaddress, () =>
       {
        bool insertsuccess = redishelper.insertset(ipaddress);
        console.foregroundcolor = consolecolor.white;
        console.writeline("ip3366.net");
        if (insertsuccess)
        {
         console.writeline("success" + ipaddress + "任務編號:" + i + "當前任務線程:" + thread.currentthread.managedthreadid);
        }
        else
        {
         console.foregroundcolor = consolecolor.red;
         console.writeline("重復插入" + ipaddress + "任務編號:" + i + "當前任務線程:" + thread.currentthread.managedthreadid);
        }
       }, (error) =>
       {
        console.foregroundcolor = consolecolor.yellow;
        console.writeline("ip3366.net");
        console.writeline("error " + ipaddress + "任務編號:" + i + "當前任務線程:" + thread.currentthread.managedthreadid);
       });
      }
      timer_ip3366_iscompleted = true;
      console.writeline("ip3366.net" + checklist.count + "條記錄,已經檢測完成,正在進行下一次檢查");
     }
     else
     {
      timer_ip3366_iscompleted = true;
      console.foregroundcolor = consolecolor.darkcyan;
      console.writeline("ip3366.net沒有需要檢查的代理ip");
     }
    }
    else
    {
     timer_ip3366_iscompleted = true;
     console.foregroundcolor = consolecolor.darkcyan;
     console.writeline("ip3366.net沒有獲取到代理ip");
    }
 
   }
  }
 }

redis第三庫使用的stackoverflow的 stackexchange.redis,代理ip不能重復儲存,所以采用的數據結構是set。存的值非常簡單就一個ip加上port,也可以存入更多相關信息,感覺沒必要。即使有這些其他的信息,也很難發揮作用。redishelper.cs如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class redishelper
 {
  private static readonly object locker = new object();
  private static connectionmultiplexer _redis;
  private const string connecttionstring = "127.0.0.1:6379,defaultdatabase=3";
  public const string redis_set_ket_success = "set_success_ip";
  private static connectionmultiplexer manager
  {
   get
   {
    if (_redis == null)
    {
     lock (locker)
     {
      if (_redis != null) return _redis;
      _redis = getmanager();
      return _redis;
     }
    }
    return _redis;
   }
  }
  private static connectionmultiplexer getmanager(string connectionstring = null)
  {
   if (string.isnullorempty(connectionstring))
   {
    connectionstring = connecttionstring;
   }
   return connectionmultiplexer.connect(connectionstring);
  }
  public static bool insertset(string value)
  {
   var db = manager.getdatabase();
   return db.setadd(redis_set_ket_success,value);
  }
 }

總結

明天補上刷服務器之家頁瀏覽量的文章吧,代碼還不夠好,ip的有效性還不高,對多線程的使用還不是很熟練

好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://www.cnblogs.com/zhangmumu/p/9269762.html

延伸 · 閱讀

精彩推薦
  • C#C#實現XML文件讀取

    C#實現XML文件讀取

    這篇文章主要為大家詳細介紹了C#實現XML文件讀取的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Just_for_Myself6702022-02-22
  • C#C#通過KD樹進行距離最近點的查找

    C#通過KD樹進行距離最近點的查找

    這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    帆帆帆6112022-01-22
  • C#WPF 自定義雷達圖開發實例教程

    WPF 自定義雷達圖開發實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下...

    WinterFish13112021-12-06
  • C#Unity3D實現虛擬按鈕控制人物移動效果

    Unity3D實現虛擬按鈕控制人物移動效果

    這篇文章主要為大家詳細介紹了Unity3D實現虛擬按鈕控制人物移動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    shenqingyu060520232410972022-03-11
  • C#C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    這篇文章主要介紹了C# 實現對PPT文檔加密、解密及重置密碼的操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下...

    E-iceblue5012022-02-12
  • C#C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    這篇文章主要介紹了C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題,簡單描述了訪問者模式的定義并結合具體實例形式分析了C#使用訪問者模式解決長...

    GhostRider9502022-01-21
  • C#深入解析C#中的交錯數組與隱式類型的數組

    深入解析C#中的交錯數組與隱式類型的數組

    這篇文章主要介紹了深入解析C#中的交錯數組與隱式類型的數組,隱式類型的數組通常與匿名類型以及對象初始值設定項和集合初始值設定項一起使用,需要的...

    C#教程網6172021-11-09
  • C#C#裁剪,縮放,清晰度,水印處理操作示例

    C#裁剪,縮放,清晰度,水印處理操作示例

    這篇文章主要為大家詳細介紹了C#裁剪,縮放,清晰度,水印處理操作示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    吳 劍8332021-12-08
主站蜘蛛池模板: 男人天堂色 | 欧美va在线高清 | 五月天精品视频在线观看 | 日韩在线视频二区 | 91.prom在线观看国产 | 国产精品怡红院永久免费 | 四虎影院入口 | 色无月| 欧美丝袜videohd | 肉搏潘金莲三级18春 | 侵犯小男生免费视频网站 | 日韩欧美高清 | 精品久久成人 | 美女被草哭| 韩国三级在线 | 成年人视频在线 | jizzjizz3d动漫| chinese真实incest chinese特色video chinese男性厕所撒尿合集 | 好大好深视频 | 99国产牛牛视频在线网站 | 99精品视频在线观看免费播放 | 天选之王漫画顾长歌免费阅读 | 男女拍拍拍免费视频网站 | 国产麻豆剧果冻传媒影视4934 | 97视频免费人人观看人人 | 女生被爆操 | 99ri在线精品视频在线播放 | 翁公与小莹在客厅激情 | chinesegay黑袜玩奴 | 欧美xxoo黑人又粗暴 | 国产乱码免费卡1卡二卡3卡四 | 无耻之徒第十一季在线观看 | 91久久精品视频 | 青青国产在线视频 | 青春草在线观看精品免费视频 | 无码中文字幕热热久久 | 成人在线免费看 | 九九99热久久精品在线6 | 国产成人小视频在线观看 | 香蕉91| 精品精品国产yyy5857香蕉 |