記一次企業級爬蟲系統升級改造(一)

 

  項目原因:程序員

    公司一直有一個半死不活的爬蟲系統,在爬取着市面上競爭公司官網的一些活動、文章等內容。正則表達式

    因爲該系統的開發人員已離職快兩年,屢次經手,現已基本失去爬取能力,每週的報表都得靠人工彙總。編程

    在咱們這個以移民業務爲主,IT部門隸屬於後勤服務的所謂的大企業的子公司裏面,英勇的前任leader滿口答應高層能夠對這個系統進行從新規劃改造,來support公司業務(主要就是爬取別人家的活動信息,本身的銷售悄悄跑過去搶客戶,順帶爬取別人的優秀文章發在本身的相關產品裏面...等等)。微信

    好吧,這些本就與我無關。但可憐的我躲角落裏仍是中槍了,前任leader幾個關鍵詞一列,會議上隨便一吹,這個偉大而光榮的任務就落在我頭上了......框架

    最主要是我手上還有其餘小矮人(介紹一下:咱們這個服務型IT部門,有「一個白雪公主,10幾個小矮人」的項目須要支持)在進行中。ide

    申請人員,沒有!申請資源,沒有!申請需求,沒有!什麼?現有爬蟲項目的交接?能找到源碼就不錯了,要啥交接!...網站

    本就不堪一擊的一件事,偶遇leader在項目啓動前離職(因此叫前任),獨剩我一我的孤苦伶仃。spa

    固然,咱們出來混程序的,有所爲有所不爲!抱怨事後,該幹還得幹,內心還得美滋滋的想着「這是領導們對我能力的一種信任」,都是爲了生活啊...excel

程序員可讓步,卻不能夠退縮,能夠羞澀,卻不能夠軟弱,總之,程序員必須是勇敢的。code

 

  現有舊爬蟲系統分析:

    時間緊迫,簡單的梳理了現有爬蟲系統代碼:

      1.系統總體構架是一個權限管控系統,爬蟲相關功能只佔總體的20%不到(具體當時的原因未知)

      2.爬蟲功能有兩套方法共存:正則表達式與AngleSharp

      3.代碼基本規範,解析活動數據方法較死,冗餘在爬取方法裏面

    貼兩個主要類出來秀一秀,讓它們也見見光,畢竟是之前的工程師花了心血的。

  1         /// <summary>
  2         /// 抓取詳細頁面
  3         /// </summary>
  4         /// <param name="Url"></param>
  5         /// <param name="titleRule"></param>
  6         /// <param name="mainRule"></param>
  7         /// <returns></returns>
  8         public void GrabPage(string Url, GH_Crawlar_GraspRule gH_Crawlar_GraspRule,string defaultXmlPath, string replaceStrXmlPath, string creator)
  9         {
 10             try
 11             {
 12                 HttpHelper httpHelper = new HttpHelper();
 13                 string result = httpHelper.RequestResult(Url, "GET", EnumHelper.GetEnumDescription((Charset)gH_Crawlar_GraspRule.Charset));
 14 
 15                 gH_Crawlar_GraspRule.TitleRule = gH_Crawlar_GraspRule.TitleRule.Replace("\\", "");
 16                 string[] strTemp = gH_Crawlar_GraspRule.TitleRule.Trim().Replace(@"\[", "[").Split('$');
 17                 string titleRule = gH_Crawlar_GraspRule.TitleRule.Trim().Replace("$", "(.*?)");
 18                 Regex regTilte = new Regex(titleRule.Trim(), RegexOptions.Singleline);
 19 
 20                 string titlt = StringHelper.ClearHtml(regTilte.Match(result).Value.ToString());
 21                 Regex mainRegex = new Regex(gH_Crawlar_GraspRule.MainRule.Trim(), RegexOptions.Singleline);
 22                 string _Content = mainRegex.Match(result).Value;
 23 
 24                 _Content = StringHelper.Filter(_Content);
 25 
 26                 string address = string.Empty;
 27                 string city = string.Empty;
 28                 string time = string.Empty;
 29                 string tel = string.Empty;
 30                 string didian = string.Empty;
 31                 string dizhi = string.Empty;
 32                 //pkid ==1  
 33                 //if (article.Pkid == 1)
 34                 //{
 35                 string titlt2 = StringHelper.ClearHtml(regTilte.Match(_Content).Value.ToString());
 36 
 37                 if (!string.IsNullOrEmpty(titlt2))
 38                 {
 39                     titlt = titlt2;
 40                 }
 41 
 42                 //清理標題規則字符
 43                 if (!string.IsNullOrEmpty(titlt))
 44                 {
 45                     foreach (string temp in strTemp)
 46                     {
 47                         if (!string.IsNullOrEmpty(temp))
 48                         {
 49                             titlt = titlt.Replace(temp, "");
 50                         }
 51                     }
 52                 }
 53 
 54                 string[] obj = GetFilter(_Content, defaultXmlPath, replaceStrXmlPath);
 55 
 56                 address = obj[0];
 57                 time = obj[1];
 58                 tel = obj[2];
 59 
 60                 //判斷地區
 61                 int region = (int)Regional.Other;
 62                 city = GetArea(titlt, address, out region);
 63           
 64                 //新增抓取信息
 65                 GH_Crawlar_GraspInfo gH_Crawlar_GraspInfo = new GH_Crawlar_GraspInfo();
 66                 GH_Crawlar_GraspInfoLogic gH_Crawlar_GraspInfoLogic = new GH_Crawlar_GraspInfoLogic();
 67 
 68                 //時間處理
 69                 List<string> times = GetTimes(time);
 70                 gH_Crawlar_GraspInfo.FullTime = time;
 71                 gH_Crawlar_GraspInfo.StartDay = string.IsNullOrEmpty(times[0]) ? "" : times[0];
 72                 gH_Crawlar_GraspInfo.StartTime = string.IsNullOrEmpty(times[1]) ? "" : times[1];
 73                 gH_Crawlar_GraspInfo.WeakDate = string.IsNullOrEmpty(times[2]) ? "" : times[2];
 74                 gH_Crawlar_GraspInfo.Title = titlt.Trim();
 75                 gH_Crawlar_GraspInfo.Url = Url;
 76                 gH_Crawlar_GraspInfo.Region = region;
 77                 gH_Crawlar_GraspInfo.Address = string.IsNullOrEmpty(address) ? "暫無" : address;
 78                 gH_Crawlar_GraspInfo.Area = city;
 79                 gH_Crawlar_GraspInfo.ArticleType = GetType(titlt.Trim());
 80                 gH_Crawlar_GraspInfo.DistributionGroup = GetsSelas(city);
 81                 gH_Crawlar_GraspInfo.Tel = string.IsNullOrEmpty(tel) ? gH_Crawlar_GraspRule.Telephone : tel;
 82                 gH_Crawlar_GraspInfo.Creator = creator;
 83                 gH_Crawlar_GraspInfo.CreateTime = DateTime.Now;
 84                 gH_Crawlar_GraspInfo.CatalogID = gH_Crawlar_GraspRule.CatalogID;
 85                 gH_Crawlar_GraspInfo.State = (int)State.Enable;
 86                 gH_Crawlar_GraspInfo.FullContent = result;
 87                 gH_Crawlar_GraspInfo.Deleted = false;
 88                 gH_Crawlar_GraspInfo.RuleID = gH_Crawlar_GraspRule.RuleID;
 89 
 90                 //根據標題和地址時間判斷若是存在不插入
 91                 if (!string.IsNullOrEmpty(titlt))
 92                 {
 93                     List<GH_Crawlar_GraspInfo> gH_Crawlar_GraspInfos = gH_Crawlar_GraspInfoLogic.GetAll(x =>
 94                         x.RuleID == gH_Crawlar_GraspInfo.RuleID &&
 95                         x.Title == titlt.Trim() && 
 96                         x.Address == gH_Crawlar_GraspInfo.Address && 
 97                         x.FullTime == time && 
 98                         x.Deleted == false).ToList();
 99                     if (gH_Crawlar_GraspInfos.Count == 0)
100                     {
101                         gH_Crawlar_GraspInfoLogic.Add(gH_Crawlar_GraspInfo);
102                     }
103                 }
104             }
105             catch (Exception ex)
106             {
107                 throw ex;
108             }
109 
110 
111         }
View Code

  

編程是一種單調的生活,所以程序員比普通人須要更多的關懷,更多的友情。

  

 

  新爬蟲系統規劃:

    公司懂這一方面的人幾乎沒有,我也僅限於在博客園偶爾看看各位大拿的相關文章,本身也就給本身的小網站爬過點美女圖片...

    要真說到一個企業級的爬蟲系統,我想總體規劃裏面爬蟲相關佔比應該不到30%纔對。

    畢竟,公司作一個爬蟲系統的目的毫不是爲了簡單的爬取一些數據。

    我分析的一個企業級的爬蟲系統應該具備的主體功能以下(還請各位資深人士多多指教):

      1.爬取指定數據

      2.規則化爬取到的數據(這一點很重要,就像咱們爬取到的活動類文章,是須要在內容中準確提煉出活動時間、活動地點、參會人數、活動類別、主講嘉賓等信息的)

      3.數據報表分析、自動郵件訂閱推送

      4.文章全文檢索(活動之外的文章數據,能夠做爲整個行業的時訊基庫存在,將成爲企業其餘網站、微信等文章資源的來源)

      5.基本統計分析

      6.輔助決策支持(固然,這一點確定是大BOSS門提出來的啦~~)

    在與boss碰頭一兩次後,作了這個系統的第一份頭腦風暴圖:

    

    通過一番講解與討論(我也不肯定,boss們是否聽明白了個人方案),boss們拍板「沒啥大問題,給你一個月本身去作吧,作完拿出來給咱們用」。

    對,你沒聽錯,就是一個月,仍是在我手上有其餘項目,而且不給任何資源的狀況下,當時就淚崩在現場!

    不過上有政策,下有對策,人總不能被尿憋死!

    因而乎過了兩天,我又新給出了更具體的方案:

      1.新系統職能主要是數據支持,再也不是單一的爬蟲系統,取了一個高大上的名字「Support雲」

      2.抽象的數據處理流程圖

      3.對boss更加抽象的最終服務方案圖

    再配上一張規劃排期的excel表格。順利的與boss暢談個把小時,最終肯定按個人排期,第一個月只作排期表的初版功能。

    歐耶~~目的終於達到,否則穩妥妥的本身把本身加班加死最後還撈不着好!

非優秀的程序員經常把空間和時間消耗殆盡,優秀的程序員則老是有足夠的空間和時間去完成編程任務,並且配合近乎完美。

    

  項目進展:

    當前已正式啓動,博主已開始進行新爬蟲系統項目的搭建。

    每週都會發一篇博客記錄相關的方案與框架代碼,直至項目最終上線,歡迎你們來吐槽~~~

 

咱們應該重視團隊的精神,一我的做用再大,也不過是一碗水中比較大的一粒水珠而已。

  這句話送給如今的boss!!!

 

原創文章,代碼都是從本身項目裏貼出來的。轉載請註明出處哦,親~~~

相關文章
相關標籤/搜索