zoukankan      html  css  js  c++  java
  • 多线程,抓取页面

    这几天在进行网站的扫黄工作,对网站,域名进行一个个的排查。当然如果真的一个个去打开看
    一下,真的是会搞死人的。有几十万的网站要去排查,那天我们几十个人搞到通宵也没搞好。不过
    通过一天的劳累,也总结了不少方法。
    首先是梁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
  • 相关阅读:
    Java实现LeetCode_0041_FirstMissingPositive
    Java实现 Leetcode 169 求众数
    Java实现 LeetCode 137 只出现一次的数字
    Java实现 LeetCode 137 只出现一次的数字
    Java实现 Leetcode 169 求众数
    TimeUnit用法
    第六章:任务执行——Java并发编程实战
    Java实现的并发任务处理实例
    java三大框架实现任务调度——IRemindService
    如何在一个div中使其子div居中
  • 原文地址:https://www.cnblogs.com/kobewang/p/1628034.html
Copyright © 2011-2022 走看看