多线程,抓取页面

这几天在进行网站的扫黄工作,对网站,域名进行一个个的排查。当然如果真的一个个去打开看
一下,真的是会搞死人的。有几十万的网站要去排查,那天我们几十个人搞到通宵也没搞好。不过
通过一天的劳累,也总结了不少方法。
首先是梁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
原文地址:https://www.cnblogs.com/kobewang/p/1628034.html