<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      多線程帶智能采集策略的采集系統(tǒng)

          去年年底的時候曾經(jīng)發(fā)過一個數(shù)據(jù)采集器網(wǎng)頁數(shù)據(jù)采集器,那是專門針對某一個網(wǎng)站來進行采集的,如果需要采集新的網(wǎng)站內容,就需要修改代碼并重新編譯。

          昨晚完成了一個帶智能策略的采集系統(tǒng)。其實,這個策略的方案三年前就想好了,那時候打算用VB做,做了一半就擱置了。現(xiàn)在用C#才終于把這個方案實現(xiàn)了。

          整個方案大概是這樣的:

          需要建立一個AC數(shù)據(jù)庫,MSSQL也行,有四個表:PageType用于記錄頁面的種類,比如列表頁和詳細頁兩類;Url表用于記錄要采集的網(wǎng)址,另外還有一個字段TypeID標明該網(wǎng)址屬于哪一種頁面類型,比如是列表頁還是詳細頁;Rule表記錄著各種規(guī)則,主要有三個字段,F(xiàn)romTypeID源頁類型,ToTypeID目的頁類型,Pattern規(guī)則;CjPage用于存儲采集到的網(wǎng)頁內容,還包含網(wǎng)址和頁面種類。

          采集策略的核心就在于規(guī)則庫Rule。

          工作過程大概這樣:
      1,采集線程從Url表抽取一個網(wǎng)址,并馬上在表中將其刪除,為了防止沖突,這個過程需要用多線程同步解決;
      2,用WebClient請求該網(wǎng)址的頁面內容;
      3,取得內容后,給線程池的線程來分析處理,本線程回到1,繼續(xù)去Url表取下一個網(wǎng)址;
      4,線程池在有空閑線程時,會調用分析函數(shù)ParsePage去處理上次獲得的頁面內容;
      5,先到Rule中取所有FromTypeID為當前網(wǎng)址TypeID;
      6,如果沒有取到任何規(guī)則Rule,則將本頁內容寫入到CjPage中;
      7,如果取到規(guī)則,那么遍歷規(guī)則,為每條規(guī)則執(zhí)行ParseUrl方法;
      8,ParseUrl根據(jù)規(guī)則的Pattern匹配到頁面內容中的所有網(wǎng)址,并記錄到Url中,規(guī)則的ToTypeID就是Url的TypeID。

          至此,整個流程就完成了。下面舉一個實際例子來說明一下:
          我要截取動網(wǎng)開發(fā)者網(wǎng)絡的所有ASP文章http://www.cndw.com/tech/asp/
          首先,在頁面類型庫中加入列表頁和詳細頁兩行,再把http://www.cndw.com/tech/asp/寫入到Url中,頁面類型是列表頁;
          其次,在Rule中加入兩條規(guī)則:
              一,從列表頁取得詳細頁的網(wǎng)址FromTypeID=1  ToTypeID=2,Pattern是· <a href="([^>]*)" target=_blank>,這條規(guī)則將會識別列表頁上的所有詳細頁的鏈接,并記入到Url中,TypeID是詳細頁;
              二,從列表頁取得列表頁的網(wǎng)址FromTypeID=1  ToTypeID=1,Pattern是<a href='([^>]*)'>下一頁<\/a>,這條規(guī)則將會取得當前列表頁上的下一頁的鏈接,并記入到Url中,TypeID還是列表頁。
          采集器工作時,如果采集的是詳細頁的內容,將會直接寫入到CjPage中,因為沒有FromTypeID=2的規(guī)則;而采集的是列表頁的內容時,就要做兩件事了,因為有兩條FromTypeID=1的規(guī)則,一件事是識別當前列表頁中所有文章的鏈接并存入Url,另一件事是識別下一列表頁鏈接并存入Url。
          由于規(guī)則具有遞歸性,使得采集器能遞歸采集到所有的文章。

          下面是一些核心源碼(沒有公開的都是一些數(shù)據(jù)層的添刪改查的代碼):

      以下是代碼片段:

      using System;
      using System.Collections.Generic;
      using System.Text;
      using System.Net;
      using System.Threading;
      using CJData;
      using System.Text.RegularExpressions;
      using NLog;

      namespace CJ
      {
          /// <summary>
          /// 寫日志委托
          /// </summary>
          /// <param name="log"></param>
          public delegate void WriteLogCallBack(String log);
          /// <summary>
          /// 采集
          /// </summary>
          public class CaiJi
          {
              private WebClient _wc;

              public WebClient Wc
              {
                  get
                  {
                      if (_wc == null) _wc = new WebClient();
                      return _wc;
                  }
              }
              private Thread thread;

              public String Name = "";
              public event WriteLogCallBack OnWriteLog;

              /// <summary>
              /// 開始工作
              /// </summary>
              public void Start()
              {
                  if (thread != null) return;
                  thread = new Thread(new ThreadStart(Work));
                  thread.Start();
              }
              /// <summary>
              /// 停止工作
              /// </summary>
              public void Stop()
              {
                  if (thread != null) thread.Abort();
                  thread = null;
              }

              private void Work()
              {
                  int times = 0;
                  while (times < 100)
                  {
                      Url url = Url.SelectOne();
                      try
                      {
                          if (url != null)
                          {
                              String page = Wc.DownloadString(url.UrlAddress);
                              if (!String.IsNullOrEmpty(page))
                              {
                                  OnWriteLog(Name + " 成功抓取:" + url.UrlAddress);
                                  times = 0;
                                  ThreadPool.QueueUserWorkItem(new WaitCallback(ParsePage), new Object[] { url, page });
                              }
                          }
                          else
                          {
                              //OnWriteLog(Name + " 沒有工作,休息半秒");
                              times++;
                              //沒有工作,休息半秒
                              Thread.Sleep(500);
                          }
                      }
                      catch (ThreadAbortException e)
                      {
                          OnWriteLog(Name + " 外部終止");
                          break;
                      }
                      catch (Exception e)
                      {
                          times++;
                          OnWriteLog(Name + " 賺取" + url.UrlAddress + "出錯,休息半秒。" + e.Message);
                          Trace.WriteLine(url.UrlAddress);
                          //出錯,休息半秒
                          Thread.Sleep(500);
                      }
                  }
                  OnWriteLog(Name + " 完成!");
              }

              private void ParsePage(Object state)
              {
                  Object[] objs = (Object[])state;
                  Url url = objs[0] as Url;
                  String page = (String)objs[1];
                  IList<Rule> rs = Rule.SelectAll(Rule._.FromTypeID, url.TypeID);
                  //if (url.PageType.TypeName == "詳細頁")
                  if (rs == null || rs.Count < 1)
                  {
                      CjPage cp = new CjPage();
                      cp.CjTime = DateTime.Now;
                      cp.Content = page;
                      cp.Url = url.UrlAddress;
                      cp.TypeID = url.TypeID;
                      cp.Insert();
                  }
                  else
                  {
                      foreach (Rule r in rs)
                      {
                          ParseUrl(url, r, page);
                      }
                  }
              }
              private void ParseUrl(Url u, Rule r, String page)
              {
                  Regex reg = new Regex(r.Pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
                  MatchCollection ms = reg.Matches(page);
                  foreach (Match m in ms)
                  {
                      Url url = new Url();
                      url.TypeID = r.ToTypeID;
                      url.UrlAddress = m.Groups[1].Value;
                      if (!url.UrlAddress.StartsWith("http://"))
                      {
                          if (url.UrlAddress.Substring(0, 1) == "/")
                          {
                              url.UrlAddress = u.UrlAddress.Substring(0, u.UrlAddress.IndexOf("/", 8)) + url.UrlAddress;
                          }
                          else
                          {
                              if (u.UrlAddress.Substring(u.UrlAddress.Length - 1) == "/")
                                  url.UrlAddress = u.UrlAddress + url.UrlAddress;
                              else
                                  if (u.UrlAddress.LastIndexOf("/") < u.UrlAddress.LastIndexOf("."))
                                      url.UrlAddress = u.UrlAddress.Substring(0, u.UrlAddress.LastIndexOf("/") + 1) + url.UrlAddress;
                                  else
                                      url.UrlAddress = u.UrlAddress + "/" + url.UrlAddress;
                          }
                      }
                      url.Insert();
                  }
              }
          }
      }

      以下是代碼片段:

      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Data;
      using System.Drawing;
      using System.Text;
      using System.Windows.Forms;
      using System.Net;

      namespace CJ
      {
          public partial class Form1 : Form
          {
              public Form1()
              {
                  InitializeComponent();
              }

              CaiJi[] cjs;
              private void button1_Click(object sender, EventArgs e)
              {
                  Button btn = sender as Button;
                  if (btn.Text == "停止")
                  {
                      foreach (CaiJi cj in cjs)
                      {
                          if (cj != null) cj.Stop();
                      }
                      cjs = null;
                      btn.Text = "開始";
                      return;
                  }

                  richTextBox1.Text = "";
                  btn.Text = "停止";

                  int k = 100;
                  if (!int.TryParse(textBox1.Text, out k)) k = 100;
                  cjs = new CaiJi[k];
                  for (int i = 0; i < cjs.Length; i++)
                  {
                      cjs[i] = new CaiJi();
                      cjs[i].Name = "線程" + i.ToString("00");
                      cjs[i].OnWriteLog += new WriteLogCallBack(cj_OnWriteLog);
                  }
                  foreach (CaiJi cj in cjs)
                  {
                      cj.Start();
                  }
              }

              void cj_OnWriteLog(string log)
              {
                  if (richTextBox1.InvokeRequired)
                  {
                      richTextBox1.Invoke(new WriteLogCallBack(cj_OnWriteLog), new object[] { log });
                  }
                  else
                  {
                      if (richTextBox1.Lines.Length > 3000) richTextBox1.Text = "";
                      richTextBox1.Text = log + Environment.NewLine + richTextBox1.Text;
                  }
              }
          }
      }


      posted @ 2007-08-18 10:45  大石頭  閱讀(8437)  評論(26)    收藏  舉報
      主站蜘蛛池模板: 九色综合狠狠综合久久| 涩涩爱狼人亚洲一区在线| 国产高清精品一区二区三区| 日韩精品国产二区三区| 赤城县| 国产精品 亚洲一区二区三区| 亚洲性日韩一区二区三区| 日韩av无码精品人妻系列| 日本亲近相奷中文字幕| 夜色福利站WWW国产在线视频| 鲁丝片一区二区三区免费| 波多野结衣av一区二区三区中文| 日韩一区二区三区日韩精品| 亚洲午夜激情久久加勒比| 成人亚洲狠狠一二三四区| 亚洲乱码日产精品bd在线看 | 久久精品亚洲精品国产色婷| 夜爽8888视频在线观看| 日韩精品中文字一区二区| 久久这里只有精品好国产| 國产AV天堂| 亚洲一区久久蜜臀av| 中文字幕av无码免费一区| 人妻中文字幕亚洲一区| 熟女视频一区二区在线观看| 黄色国产精品一区二区三区 | 中国熟妇毛多多裸交视频| 少妇人妻综合久久中文字幕| 国产精品一区二区三区自拍| 国精偷拍一区二区三区| 国产中文99视频在线观看| 性色在线视频精品| 一色桃子中出欲求不满人妻| 久久久久免费看成人影片| 亚洲av熟女国产一二三| 岛国av在线播放观看| 久久99精品久久久大学生| 日本一区二区中文字幕久久| 天天做天天爱夜夜爽女人爽| 亚洲国产日韩欧美一区二区三区 | 成人无码潮喷在线观看|