[c#] 郵件群發工具的編寫(一)郵件地址批量提取


    郵件群發軟件的編寫(一)


工欲善其事,必先利其器

   很多時候,由於是自己做站的關系,經常會碰到郵件群發這個概念。群里也經常有人討論郵件群發的技術問題,今天趁着中午的休息時間,整理一下思路研究一下。我個人其實並不喜歡郵件群發,只是喜歡研究郵件群發的原理。最近論壇里很多人都要求開發一款特制的郵件群發器,所以我就選擇在這里同步這款郵件群發工具的制作步驟,供新手參考,老鳥繞道。

第一步:郵箱批量采集器的制作。

    郵箱批量采集,要選擇好采集的頁面,我在這里就選擇163郵箱吧。因為這種頁面采集比較中規中矩。

http://blog.163.com/findFriend.do

看出什么來了嗎?對,這個頁面全部是163會員的信息。其中這個頁面的html文本里面還有我們要找的郵箱資料。

紅框里面的就是我們要找的郵箱地址的“base64字符串格式”,只要提取出來后,將其變化為普通的文本就可以了,這在.net里很好解決。

下面的要做事就是用http嗅探器抓取參數資料了。這一步就直接省略...

接下來就直接貼上代碼了。

  

View Code
  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

這樣郵箱地址批量提取就完成啦,最后就是您對這些數據的處理了。教程每天更新,歡迎繼續關注!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM