郵件群發軟件的編寫(一)
很多時候,由於是自己做站的關系,經常會碰到郵件群發這個概念。群里也經常有人討論郵件群發的技術問題,今天趁着中午的休息時間,整理一下思路研究一下。我個人其實並不喜歡郵件群發,只是喜歡研究郵件群發的原理。最近論壇里很多人都要求開發一款特制的郵件群發器,所以我就選擇在這里同步這款郵件群發工具的制作步驟,供新手參考,老鳥繞道。 第一步:郵箱批量采集器的制作。 郵箱批量采集,要選擇好采集的頁面,我在這里就選擇163郵箱吧。因為這種頁面采集比較中規中矩。 http://blog.163.com/findFriend.do 看出什么來了嗎?對,這個頁面全部是163會員的信息。其中這個頁面的html文本里面還有我們要找的郵箱資料。 紅框里面的就是我們要找的郵箱地址的“base64字符串格式”,只要提取出來后,將其變化為普通的文本就可以了,這在.net里很好解決。 下面的要做事就是用http嗅探器抓取參數資料了。這一步就直接省略... 接下來就直接貼上代碼了。
![]() 1 // 2 //版權:無 3 //作者:凌晨的搜索者 4 //出自:http://www.cnblogs.com/uu102 ,轉載請加上版權信息 5 // 6 using System; 7 using System.Collections.Generic; 8 using System.Linq; 9 using System.Text; 10 using System.Web; 11 using System.Text.RegularExpressions; 12 using System.Net.Mail; 13 using System.Net; 14 namespace System 15 { //郵箱提取控制類 16 public class MailUtil 17 { 18 public int Index { get; set; } 19 public int Type { get; set; } 20 public string Gender { get; set; } 21 public string Online { get; set; } 22 public string Province { get; set; } 23 public string City { get; set; } 24 public bool HasNext { get; set; } 25 #region 構造函數 26 public MailUtil() 27 { 28 this.Init(1, 5, "", "", "", ""); 29 } 30 public MailUtil(int index) 31 { 32 this.Init(index, 5, "", "", "", ""); 33 } 34 public MailUtil(int index, int type) 35 { 36 this.Init(index, type, "", "", "", ""); 37 } 38 public MailUtil(int index, int type, string gender) 39 { 40 this.Init(index, type, gender, "", "", ""); 41 } 42 public MailUtil(int index, int type, string gender, string online) 43 { 44 this.Init(index, type, gender, online, "", ""); 45 } 46 public MailUtil(int index, int type, string gender, string online, string province) 47 { 48 this.Init(index, type, gender, online, province, ""); 49 } 50 public MailUtil(int index, int type, string gender, string online, string province, string city) 51 { 52 this.Init(index, type, gender, online, province, city); 53 } 54 #endregion 55 private void Init(int index, int type, string gender,string online, string province, string city) 56 { 57 index = 1; 58 this.Index = index; 59 this.Type = type; 60 this.Gender = gender; 61 this.Online = online; 62 this.Province = province; 63 this.City = city; 64 this.HasNext = true; 65 this.Province = HttpUtility.UrlEncode(Encoding.GetEncoding("utf-8").GetBytes(this.Province)); 66 this.City = HttpUtility.UrlEncode(Encoding.GetEncoding("utf-8").GetBytes(this.City)); 67 68 } 69 private string VisitSite() 70 { 71 string url = "http://blog.163.com/findFriend.do"; 72 StringBuilder sb = new StringBuilder(); 73 sb.AppendFormat("{0}?index={1}&type={2}",url,this.Index,this.Type); 74 if(this.Gender!="") sb.AppendFormat("&{0}",this.Gender); 75 if(this.Province!="")sb.AppendFormat("&{0}",this.Province); 76 if(this.City!="")sb.AppendFormat("&{0}",this.City); 77 if(this.Online!="")sb.AppendFormat("&{0}",this.Online); 78 79 string html = UUHttpHelper.GetHtml(sb.ToString(), "gbk"); 80 return html; 81 } 82 public Dictionary<string,LinkMan> Extract() 83 { 84 LinkMan linkman =null; 85 86 Dictionary<string, LinkMan> linkmans = new Dictionary<string, LinkMan>(); 87 string html = VisitSite(); 88 this.HasNext = html.Contains("下一頁") ; 89 if (!this.HasNext) return linkmans; 90 MatchCollection matches = new Regex(@"openurl\('(?'base64'[^']+)','profile'\)""\s*class=""nick""\>(?'nick'[^<>]*)\s*\</a\>", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace).Matches(html); 91 foreach (Match match in matches) 92 { 93 linkman = new LinkMan(); 94 linkman.Base64String = match.Groups["base64"].Value; 95 string unicode=Encoding.GetEncoding("Gbk").GetString(Convert.FromBase64String(linkman.Base64String)); 96 linkman.Email = unicode.Contains("@126")?(string.Format("{0}.com",unicode)):(string.Format("{0}@163.com",unicode)); 97 linkman.Nick = match.Groups["nick"].Value; 98 linkmans.Add(linkman.Base64String, linkman); 99 } 100 matches = new Regex(@"<a\s*[^>]*>(?'area'[^<]*)</a>\s*</div>\s*</div>\s*<div class=""nav"">\s*<a\s*href=""javascript:void\(0\);""\s*(onclick=""gFindFriend.openurl\s*\('(?'base64'[^']+)','blog'\)"")*>", RegexOptions.IgnoreCase).Matches(html); 101 foreach (Match match in matches) 102 { 103 linkmans[match.Groups["base64"].Value].Area = match.Groups["area"].Value; 104 } 105 this.Index++; 106 return linkmans; 107 108 } 109 110 } 111 /// <summary> 112 /// 聯系人信息 113 /// </summary> 114 public class LinkMan 115 { 116 /// <summary> 117 /// 昵稱 118 /// </summary> 119 public string Nick { get; set; } 120 /// <summary> 121 /// 郵箱地址前綴的base64字符串 122 /// </summary> 123 public string Base64String { get; set; } 124 /// <summary> 125 /// 郵箱地址 126 /// </summary> 127 public string Email { get; set; } 128 /// <summary> 129 /// 性別 130 /// </summary> 131 public string Sex { get; set; } 132 /// <summary> 133 /// 地區 134 /// </summary> 135 public string Area { get; set; } 136 /// <summary> 137 /// 省份 138 /// </summary> 139 public string Province { get; set; } 140 /// <summary> 141 /// 城市 142 /// </summary> 143 public string City { get; set; } 144 /// <summary> 145 /// 年齡 146 /// </summary> 147 public int Age { get; set; } 148 } 149 public class TestClass 150 { 151 public static bool Paused = false; 152 static MailUtil mailUtil = new MailUtil(); 153 static Dictionary<string, LinkMan> linkmans = new Dictionary<string, LinkMan>(); 154 public static Dictionary<string, LinkMan> TestMethod(System.Windows.Forms.ListView listView) 155 { 156 157 System.Threading.Thread thread = new System.Threading.Thread(new System.Threading.ThreadStart(delegate 158 { 159 while (mailUtil.HasNext) 160 { 161 162 Dictionary<string, LinkMan> list = mailUtil.Extract(); 163 foreach (KeyValuePair<string, LinkMan> kvp in list) 164 { 165 if (!linkmans.ContainsKey(kvp.Key)) 166 { 167 linkmans.Add(kvp.Key, kvp.Value); 168 System.Windows.Forms.ListViewItem viewItem = listView.Items.Add(linkmans.Count.ToString()); 169 viewItem.SubItems.Add(kvp.Value.Nick); 170 viewItem.SubItems.Add(kvp.Value.Email); 171 viewItem.SubItems.Add(kvp.Value.Area); 172 } 173 } 174 if (Paused) 175 break; 176 } 177 if (linkmans.Count == 0) throw new Exception("沒有找到任何數據"); 178 179 })); 180 thread.Start(); 181 return linkmans; 182 } 183 } 184 185 }
這個類調用起來相當簡單,直接new一個實例之后,調用Extract()就可以了。但是這樣的話就只能獲取所有結果的第一頁了,后面還有很多的頁面就無法抓去了,因此要將里面一個url地址的index參數加1,並且還要判斷返回的html頁里面是不是含有“下一頁”,沒有的話就不用繼續再抓了 所以我在后面結尾處又加上了一個測試類,供大家直接調用,省去了很多麻煩。因為是靜態類,所直接這樣調用就可以了。 TestClass.TestMethod(listView1);//這個中間的listView1是你實際上添加到你代碼中的控件名稱,當然,前提是這個控件已經添加好了相對應的colume
這樣郵箱地址批量提取就完成啦,最后就是您對這些數據的處理了。教程每天更新,歡迎繼續關注! |