多线程,抓取页面

这几天在进行网站的扫黄工作,对网站,域名进行一个个的排查。当然如果真的一个个去打开看
一下,真的是会搞死人的。有几十万的网站要去排查,那天我们几十个人搞到通宵也没搞好。不过
通过一天的劳累,也总结了不少方法。
首先是梁Boss的批处理文件,it is a real good  idea to open a batch web pages.如果单一的
去打开一个个的网页,肯定是吃不消地。只需要稍稍应用下批处理文件就可以一下打开好几十个网页
。具体操作如下:1.新建txt文件,输入内容如下
start http://www.baidu.cn
start http://www.baidu2.cn
start http://www.baidu3.cn
start http://www.baidu4.cn
....
但是 如果打开过多浏览器就会崩溃,这时就需要增加 一个
pause ,每打开多少就暂停一下。
当然这样子操作 还是要我们去肉眼判断。能不能将工作再简化一下呢,毕竟是几十万的数据啊。
我的选择是抓取网页内容,先过滤一遍关键字,因为通过网页内容文字与关键字的匹配,不能说
百分百的正确,也能达到百分七八十的正确率,再对过滤出来的网页进行人工审核,工作量减轻一
大半。
所以,就有了以下这个程序“多线程-狂抓页面”。为什么选择多线程 而不是线程池?因为多线程
我可以将线程数组设到100或1000,线程池的容量有限,还有就是我也不知道如何将线程池开到成百
上千个线程去执行,而又不冲突,主要还是对线程池不是很掌握。话不多说,贴上代码,代码是在
小谢的代码基础上的改进,在此表示感谢。
程序效果图如下:
多线程,抓取页面
下面进行一步步分析,如何用 多线程-狂抓页面

声明一个域名队列,


 


代码
 1  Queue < string >  domainqueue  =   new  Queue < string > ();
 2  所有要查域名都放在队列里
 3  foreach  ( string  domain  in  domains)
 4  {
 5         // 所有域名进队列
 6        domainqueue.Enqueue(domain);
 7  }
 8 
 9  声明一个线程数组:并启动
10       threads  =   new  Thread[threadNum];
11       for  ( int  i  =   0 ; i  <  threadNum; i ++ )
12      {
13                  threads[i]  =   new  Thread( new  ThreadStart(RunThread));
14                  threads[i].Name  =   " checkDomain " + i;
15                  threads[i].IsBackground  =   true ;
16                   // 启动
17                 threads[i].Start();
18      }
19 
20  线程执行代理函数 (RunThread)
21     // 执行线程
22      public   void  RunThread()
23          {
24              Thread current_thread  =  Thread.CurrentThread; // 当前线程
25              MyInvoke mi  =   new  MyInvoke(rtb_result.AppendText);  // 代理,显示线程结果
26              MyInvoke mi2  =   new  MyInvoke(rtb_illegal.AppendText); // 代理,显示过滤结果
27          // 当队列存在
28               while  (domainqueue.Count  >   0 )
29              {
30           // 出队列
31                   string  domain  =  domainqueue.Dequeue();
32                   try
33                  {
34              // 同步显示
35                      rtb_result.Invoke(mi, " 域名:[ " + domain + " ]   当前线程:[ " + current_thread.Name + " ] "   +   " \r\n " );
36                       string  keyword = "" ;
37                       // 若扫描到,过滤结果
38                       if  (ScanDomain(domain,  out  keyword))  // 扫描函数
39                      {
40                          rtb_illegal.Invoke(mi2, domain  +   " : "   +  keyword  +   " \r\n " );
41                      }
42                       // 带www主机头的扫描
43                       string  host  =   " www. " ;
44                       if  (cbx_www.Checked)
45                      {
46                           if  (ScanDomain(host  +  domain,  out  keyword))
47                          {
48                              rtb_illegal.Invoke(mi2,host +  domain  +   " : "   +  keyword  +   " \r\n " );
49                          }
50                      }
51                  }
52                   catch  (Exception ex)
53                  {
54                      rtb_result.Invoke(mi,ex.ToString() + " \r\n " );
55                  }
56              }
57 
58          }
59 
60  // 扫描函数
61      // 扫描域名是否含非法信息
62           private   bool  ScanDomain( string  domain, out   string  keyword)
63          {
64              keyword  =   null ;
65           // 抓取页面内容并过滤 html标记
66               string  pageContent  =  PageOp.NoHTML(PageOp.GetPageContent(domain));
67           // 抓取页面的内容,进行非法关键字匹配
68               return  PageOp.IsIllegal(pageContent, out  keyword);
69          }


其中抓取页面我用的webrequest对象,但是webrequest对有些网页的抓取是抓不到的,但他又比xmlhttp抓取要快,
所以我说先用webrequest 抓取,抓不到的再用xmlhttp  去抓取。
测试的效果还不错,如果网站是有网页并且可访问,1000个开100个线程也就1分钟样子就搞定,难的是有些域名是
没有解析的抓不到。也会造成网络堵塞,qq都掉了2次,抓太多也不好的啊。呵呵
程序有待改进,还请朋友们给我指点:
源码下载 http://kobewang.cn/article/WinForm/34.html

你可能感兴趣的:(多线程)