之前做的采集程序, 是单线程的, 一个图片列表, 要等着一一采完....浪费了不少时间, 正好今天家里带宽升级, 可以使用多线程采集了.... 连夜改进原来的程序. 使用多线程去采集....
设定思路: 采集目标: http://www.8kmm.com, 已知网址列表(List保存), 应用多线程(Thread)读取该列表, 获取url时不能重复(加锁Lock). 允许无序采集!
先放个美女提提神!
多线程核心代码:
1 #region 全局变量 2 //线程列表 3 List<Thread> threadslList = new List<Thread>(); 4 //Url列表 5 List<string> uUrls = new List<string>(); 6 //处理完毕的列表 7 List<string> OkUrls = new List<string>(); 8 //成功取得的美女图片数量 9 public int ImgCount = 0; 10 #endregion 11 12 13 //取图开始 按钮事件 14 private void lbtnGetWebImgStart_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 15 { 16 lbtnGetWebImgStart.Enabled = false; 17 GetWebSiteImg(); 18 } 19 20 //取图停止 按钮事件 21 private void lbtnGetWebImgStop_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 22 { 23 try 24 { 25 foreach (Thread t in threadslList) 26 { 27 if (t != null) 28 { 29 t.Abort(); 30 } 31 } 32 } 33 catch (Exception ex) 34 { 35 WriteLog("停止失败:" + ex.Message); 36 } 37 finally 38 { 39 lbtnGetWebImgStart.Enabled = true; 40 } 41 } 42 43 /// <summary> 44 /// 获取图片主方法 45 /// </summary> 46 private void GetWebSiteImg() 47 { 48 try 49 { 50 ImgCount = 0; 51 OkUrls.Clear(); 52 uUrls.Clear(); 53 threadslList.Clear(); //先初始化以上 54 string[] urls = txtUrl.Text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); 55 lblC.Text = urls.Length.ToString(CultureInfo.InvariantCulture); 56 uUrls = new List<string>(urls); 57 for (int i = 0; i < int.Parse(numThreadUD.Text); i++) // 循环创建线程 58 { 59 Thread t = new Thread(Task); 60 t.Name = i.ToString(); 61 t.IsBackground = true; 62 threadslList.Add(t); 63 t.Start(); 64 } 65 } 66 catch (Exception ex) 67 { 68 WriteLog(ex.Message); 69 } 70 } 71 72 73 public void Task() 74 { 75 while (uUrls.Count > 0) 76 { 77 lblMsg.Text = string.Format("剩余:{0},已访问:{1},当前线程数:{2}", uUrls.Count, (OkUrls.Count + 1), threadslList.Count); 78 string url = GetUrl(); 79 if (url == "") 80 { 81 break; 82 } 83 else 84 { 85 if (GetHttpImg(url) == 200)//只有状态200才是正常的, GetHttpImg是我封装的方法, 获取网页, 正则取得所有合规范的图片. 86 { 87 OkUrls.Add(url); 88 lblInfoStart.Text = (int.Parse(lblInfoStart.Text) + 1).ToString(CultureInfo.InvariantCulture); 89 WriteHtml(txtUrl.Text); 90 if (lblC.Text == lblInfoStart.Text)//判断当前数量是否已是总数. 91 { 92 lblMsg.Text = "完成"; 93 } 94 } 95 } 96 } 97 } 98 99 100 /// <summary> 101 /// 线程加锁,防止多个线程同时从list里面取出第一个 102 /// </summary> 103 /// <returns></returns> 104 public string GetUrl() 105 { 106 lock ("GetUrl") 107 { 108 if (uUrls.Count > 0) 109 { 110 string url = uUrls[0]; 111 uUrls.RemoveAt(0); 112 return url; 113 } 114 else 115 { 116 return ""; 117 } 118 } 119 }
代码超级简单, 测试抓取几个列表, 没有问题, 等会用它去抓更多MM。。。