`
Arthur_Wen
  • 浏览: 29946 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java 抓图程序的实现

    博客分类:
  • Java
阅读更多
Java抓图程序的实现(改进版) 收藏

转自:http://blog.csdn.net/binyao02123202/archive/2010/07/17/5741519.aspx

主要难点:

1.并发线程的控制 采用了JDK5的UTIL包里的concurrent子包

2.去重

3.序列化

运行方法:java -Xms128M -Xmx512M -jar JavaCrawler.jar http://foxhq.com/ C:/a.log 0 D:/pic D:/url.tmp D:/img.tmp

SimpleBloomFilter.java



view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······15001.package com.hengking.crawl;  
02.import java.io.Serializable;  
03.import java.util.BitSet;  
04. 
05.public class SimpleBloomFilter  implements Serializable {  
06.      
07.      
08.        /** 
09.     *  
10.     */ 
11.    private static final long serialVersionUID = 1L;  
12.        private   final int   DEFAULT_SIZE = 2 << 24;  
13.        private   final int[] seeds        = new int[] { 7, 11, 13, 31, 37, 61, };  
14.        private  BitSet             bits         = new BitSet(DEFAULT_SIZE);  
15.        private   SimpleHash[]       func         = new SimpleHash[seeds.length];  
16.//      public  void main(String[] args) {  
17.//          String value = "stone2083@yahoo.cn";  
18.//          SimpleBloomFilter filter = new SimpleBloomFilter();  
19.//          System.out.println(filter.contains(value));  
20.//          filter.add(value);  
21.//          System.out.println(filter.contains(value));  
22.//      }  
23.        public SimpleBloomFilter() {  
24.            for (int i = 0; i < seeds.length; i++) {  
25.                func[i] = new SimpleHash(DEFAULT_SIZE, seeds[i]);  
26.            }  
27.        }  
28.        public void add(String value) {  
29.            for (SimpleHash f : func) {  
30.                bits.set(f.hash(value), true);  
31.            }  
32.        }  
33.        public boolean contains(String value) {  
34.            if (value == null) {  
35.                return false;  
36.            }  
37.            boolean ret = true;  
38.            for (SimpleHash f : func) {  
39.                ret = ret && bits.get(f.hash(value));  
40.            }  
41.            return ret;  
42.        }  
43.      
44.    public   class SimpleHash implements Serializable {  
45.        private int cap;  
46.        private int seed;  
47.        public SimpleHash(int cap, int seed) {  
48.            this.cap = cap;  
49.            this.seed = seed;  
50.        }  
51.        public int hash(String value) {  
52.            int result = 0;  
53.            int len = value.length();  
54.            for (int i = 0; i < len; i++) {  
55.                result = seed * result + value.charAt(i);  
56.            }  
57.            return (cap - 1) & result;  
58.        }  
59.    }  
60.    @Override 
61.    public String toString() {  
62.        // TODO Auto-generated method stub  
63.        return super.toString();  
64.    }  
65.      
66.      
67.} 
package com.hengking.crawl;
import java.io.Serializable;
import java.util.BitSet;

public class SimpleBloomFilter  implements Serializable {


/**
*
*/
private static final long serialVersionUID = 1L;
private   final int   DEFAULT_SIZE = 2 << 24;
    private   final int[] seeds        = new int[] { 7, 11, 13, 31, 37, 61, };
    private  BitSet             bits         = new BitSet(DEFAULT_SIZE);
    private   SimpleHash[]       func         = new SimpleHash[seeds.length];
//     public  void main(String[] args) {
//         String value = "stone2083@yahoo.cn";
//         SimpleBloomFilter filter = new SimpleBloomFilter();
//         System.out.println(filter.contains(value));
//         filter.add(value);
//         System.out.println(filter.contains(value));
//     }
    public SimpleBloomFilter() {
        for (int i = 0; i < seeds.length; i++) {
            func[i] = new SimpleHash(DEFAULT_SIZE, seeds[i]);
        }
    }
    public void add(String value) {
        for (SimpleHash f : func) {
            bits.set(f.hash(value), true);
        }
    }
    public boolean contains(String value) {
        if (value == null) {
            return false;
        }
        boolean ret = true;
        for (SimpleHash f : func) {
            ret = ret && bits.get(f.hash(value));
        }
        return ret;
    }

public   class SimpleHash implements Serializable {
        private int cap;
        private int seed;
        public SimpleHash(int cap, int seed) {
            this.cap = cap;
            this.seed = seed;
        }
        public int hash(String value) {
            int result = 0;
            int len = value.length();
            for (int i = 0; i < len; i++) {
                result = seed * result + value.charAt(i);
            }
            return (cap - 1) & result;
        }
    }
@Override
public String toString() {
// TODO Auto-generated method stub
return super.toString();
}


}


UtilSeriz.java

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······15001.package com.hengking.crawl;  
02.import java.io.*;  
03.public class UtilSeriz   
04.{  
05.    /** 
06.     *将对象序列化到磁盘文件中 
07.     *@param 
08.     *@throwsException 
09.     */ 
10.    public static  void writeObject(Object o,String strPath) throws Exception{  
11.       File f=new File(strPath);  
12.       if(f.exists()){  
13.           f.delete();  
14.       }  
15.       FileOutputStream os=new FileOutputStream(f);  
16.       //ObjectOutputStream 核心类  
17.       ObjectOutputStream oos=new ObjectOutputStream(os);  
18.       oos.writeObject(o);  
19.       oos.close();  
20.       os.close();  
21.    }  
22.      
23.    /** 
24.     *反序列化,将磁盘文件转化为对象 
25.     *@paramf 
26.     *@return 
27.     *@throwsException 
28.     */ 
29.    public static Object readObject(String strPath) throws Exception{  
30.        File f=new File(strPath);  
31.        if(!f.exists())  
32.        {  
33.            return null;  
34.        }  
35.       InputStream is=new FileInputStream(f);  
36.       //ObjectOutputStream 核心类  
37.       ObjectInputStream ois=new ObjectInputStream(is);  
38.       return ois.readObject();  
39.    }  
40.      
41.} 
package com.hengking.crawl;
import java.io.*;
public class UtilSeriz
{
/**
     *将对象序列化到磁盘文件中
     *@param
     *@throwsException
     */
    public static  void writeObject(Object o,String strPath) throws Exception{
       File f=new File(strPath);
       if(f.exists()){
           f.delete();
       }
       FileOutputStream os=new FileOutputStream(f);
       //ObjectOutputStream 核心类
       ObjectOutputStream oos=new ObjectOutputStream(os);
       oos.writeObject(o);
       oos.close();
       os.close();
    }
   
    /**
     *反序列化,将磁盘文件转化为对象
     *@paramf
     *@return
     *@throwsException
     */
    public static Object readObject(String strPath) throws Exception{
    File f=new File(strPath);
    if(!f.exists())
    {
    return null;
    }
       InputStream is=new FileInputStream(f);
       //ObjectOutputStream 核心类
       ObjectInputStream ois=new ObjectInputStream(is);
       return ois.readObject();
    }

}


SearchCrawler.java

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······15001.package com.hengking.crawl;  
02.import java.awt.image.BufferedImage;  
03.import java.io.BufferedInputStream;  
04.import java.io.BufferedReader;  
05.import java.io.BufferedWriter;  
06.import java.io.File;  
07.import java.io.FileOutputStream;  
08.import java.io.FileWriter;  
09.import java.io.IOException;  
10.import java.io.InputStreamReader;  
11.import java.net.URL;  
12.import java.text.SimpleDateFormat;  
13.import java.util.ArrayList;  
14.import java.util.Calendar;  
15.import java.util.Date;  
16.import java.util.HashMap;  
17.import java.util.LinkedHashSet;  
18.import java.util.concurrent.Callable;  
19.import java.util.concurrent.ExecutorService;  
20.import java.util.concurrent.Executors;  
21.import java.util.concurrent.Semaphore;  
22.import java.util.regex.Matcher;  
23.import java.util.regex.Pattern;  
24.import javax.imageio.ImageIO;  
25.import com.hengking.crawl.po.PoCalSearch;  
26.import com.hengking.crawl.po.PoDownload;  
27. 
28. 
29./*** 
30. * 说明:抓图工具 
31. * @author 君望永远 
32. * 
33. */ 
34.public class SearchCrawler implements Runnable{  
35.   
36.    /* disallowListCache缓存robot不允许搜索的URL。 Robot协议在Web站点的根目录下设置一个robots.txt文件, 
37.     *规定站点上的哪些页面是限制搜索的。 搜索程序应该在搜索过程中跳过这些区域,下面是robots.txt的一个例子: 
38.    # robots.txt for http://somehost.com/ 
39.    User-agent: * 
40.    Disallow: /cgi-bin/ 
41.    Disallow: /registration # /Disallow robots on registration page 
42.    Disallow: /login 
43.    */ 
44.    public static SimpleBloomFilter  filterUrl;  
45.    public static  SimpleBloomFilter filterImg;   
46.    private HashMap< String,ArrayList< String>> disallowListCache = new HashMap< String,ArrayList< String>>();   
47.    ArrayList< String> errorList= new ArrayList< String>();//错误信息   
48.    ArrayList< String> result=new ArrayList< String>(); //搜索到的结果   
49.    String startUrl;//开始搜索的起点  
50.    LinkedHashSet<String> toCrawlList = new LinkedHashSet<String>();  
51.    boolean caseSensitive=false;//是否区分大小写  
52.    boolean limitHost=false;//是否在限制的主机内搜索  
53.    private static String outdir;  
54.    
55.    private static String seroutdir;  
56.    private static String seroutdirimg;  
57.    private boolean blnFlag=false;  
58.      
59.    private static  PoCalSearch ps=null;  
60.    private static PoDownload pd=null;  
61.      
62.    //300个图片分析线程  
63.    private static ExecutorService   execImg;  
64.    final Semaphore sempImg = new Semaphore(300);  
65.      
66.    //30个网页分析线程  
67.    private static ExecutorService   execPage;  
68.    final Semaphore sempPage = new Semaphore(30);  
69.      
70.    private ArrayList<ParsePage> arrPar=new ArrayList<ParsePage>();  
71.      
72.    //记录抓图结果  
73.    private static BufferedWriter bw = null;    
74.      
75.  public SearchCrawler(String startUrl)  
76.  {  
77.   this.startUrl=startUrl;  
78.   
79.  }  
80.   public ArrayList< String> getResult(){  
81.       return result;  
82.   }  
83.  public void run(){//启动搜索线程  
84.       new Thread(new TimeWrite2File()).start();  
85.       blnFlag=true;  
86.       crawl(startUrl,limitHost,caseSensitive);  
87.         
88.  }  
89.     
90.    //检测URL格式  
91.  private URL verifyUrl(String url) {  
92.    // 只处理HTTP URLs.  
93.    if (!url.toLowerCase().startsWith("http://"))  
94.      return null;  
95.    URL verifiedUrl = null;  
96.    try {  
97.      verifiedUrl = new URL(url);  
98.    } catch (Exception e) {  
99.      return null;  
100.    }  
101.    return verifiedUrl;  
102.  }  
103.  // 检测robot是否允许访问给出的URL.  
104. private boolean isRobotAllowed(URL urlToCheck) {   
105.    String host = urlToCheck.getHost().toLowerCase();//获取给出RUL的主机   
106.    //System.out.println("主机="+host);  
107.    // 获取主机不允许搜索的URL缓存   
108.    ArrayList< String> disallowList =disallowListCache.get(host);   
109.    // 如果还没有缓存,下载并缓存。   
110.    if (disallowList == null) {   
111.      disallowList = new ArrayList< String>();   
112.      try {   
113.        URL robotsFileUrl =new URL("http://" + host + "/robots.txt");   
114.        BufferedReader reader =new BufferedReader(new InputStreamReader(robotsFileUrl.openStream()));   
115.        // 读robot文件,创建不允许访问的路径列表。   
116.        String line;   
117.        while ((line = reader.readLine()) != null) {   
118.          if (line.indexOf("Disallow:") == 0) {//是否包含"Disallow:"   
119.            String disallowPath =line.substring("Disallow:".length());//获取不允许访问路径   
120.            // 检查是否有注释。   
121.            int commentIndex = disallowPath.indexOf("#");   
122.            if (commentIndex != - 1) {   
123.              disallowPath =disallowPath.substring(0, commentIndex);//去掉注释   
124.            }   
125.               
126.            disallowPath = disallowPath.trim();   
127.            disallowList.add(disallowPath);   
128.           }   
129.         }   
130.        // 缓存此主机不允许访问的路径。   
131.        disallowListCache.put(host, disallowList);   
132.      } catch (Exception e) {   
133.              return true; //web站点根目录下没有robots.txt文件,返回真  
134.      }   
135.    }   
136.       
137.    String file = urlToCheck.getFile();   
138.    //System.out.println("文件getFile()="+file);  
139.    for (int i = 0; i < disallowList.size(); i++) {   
140.      String disallow = disallowList.get(i);   
141.      if (file.startsWith(disallow)) {   
142.        return false;   
143.      }   
144.    }   
145.    return true;   
146.  }   
147. 
148.   
149.  private String downloadPage(URL pageUrl) {  
150.     try {  
151.         
152.          
153.          
154.         // Open connection to URL for reading.  
155.         BufferedReader reader =  
156.          new BufferedReader(new InputStreamReader(pageUrl.openStream()));  
157.          
158.           
159.        // Read page into buffer.  
160.        String line;  
161.        StringBuffer pageBuffer = new StringBuffer();  
162.        while ((line = reader.readLine()) != null) {  
163.          pageBuffer.append(line);  
164.        }  
165.          
166.        return pageBuffer.toString();  
167.     } catch (Exception e) {  
168.         e.printStackTrace();  
169.     }  
170.     return null;  
171.  }  
172.  // 从URL中去掉"www"  
173.  private String removeWwwFromUrl(String url) {  
174.    int index = url.indexOf("://www.");  
175.    if (index != -1) {  
176.      return url.substring(0, index + 3) +  
177.        url.substring(index + 7);  
178.    }  
179.    return (url);  
180.  }  
181.  // 解析页面并找出链接  
182.  private ArrayList< String> retrieveLinks(URL pageUrl, String pageContents,   
183.    boolean limitHost)  
184.  {  
185.    // 用正则表达式编译链接的匹配模式。  
186.    Pattern p =Pattern.compile("<a\\s+href\\s*=\\s*\"?(.*?)[\"|>]",Pattern.CASE_INSENSITIVE);  
187.    Matcher m = p.matcher(pageContents);  
188.      
189.    ArrayList< String> linkList = new ArrayList< String>();  
190.    while (m.find()) {  
191.      String link = m.group(1).trim();  
192.        
193.      if (link.length() < 1) {  
194.        continue;  
195.      }  
196.      // 跳过链到本页面内链接。  
197.      if (link.charAt(0) == '#') {  
198.        continue;  
199.      }  
200.        
201.      if (link.indexOf("mailto:") != -1) {  
202.        continue;  
203.      }  
204.       
205.      if (link.toLowerCase().indexOf("javascript") != -1) {  
206.        continue;  
207.      }  
208.      if (link.indexOf("://") == -1){  
209.        if (link.charAt(0) == '/') {//处理绝对地    
210.          link = "http://" + pageUrl.getHost()+":"+pageUrl.getPort()+ link;  
211.        } else {           
212.          String file = pageUrl.getFile();  
213.          if (file.indexOf('/') == -1) {//处理相对地址  
214.            link = "http://" + pageUrl.getHost()+":"+pageUrl.getPort() + "/" + link;  
215.          } else {  
216.            String path =file.substring(0, file.lastIndexOf('/') + 1);  
217.            link = "http://" + pageUrl.getHost() +":"+pageUrl.getPort()+ path + link;  
218.          }  
219.        }  
220.      }  
221.      int index = link.indexOf('#');  
222.      if (index != -1) {  
223.        link = link.substring(0, index);  
224.      }  
225.      link = removeWwwFromUrl(link);  
226.      URL verifiedLink = verifyUrl(link);  
227.      if (verifiedLink == null) {  
228.        continue;  
229.      }  
230.      /* 如果限定主机,排除那些不合条件的URL*/ 
231.      if (limitHost &&  
232.          !pageUrl.getHost().toLowerCase().equals(  
233.            verifiedLink.getHost().toLowerCase()))  
234.      {  
235.        continue;  
236.      }  
237.      // 跳过那些已经处理的链接.  
238.      if(filterUrl.contains(link))  
239.      {  
240.          logEvent("匹配了:"+link);  
241.          continue;  
242.      }  
243.      else 
244.      {  
245.          filterUrl.add(link);  
246.      }  
247.        
248.       linkList.add(link);  
249.    }  
250.   return (linkList);  
251.  }  
252.    
253.    
254.    
255.    
256.  // 解析页面并找出链接  
257.  private ArrayList< String> retrieveImgLinks(URL pageUrl, String pageContents,   
258.    boolean limitHost)  
259.  {  
260.    // 用正则表达式编译链接的匹配模式。  
261.    Pattern p =Pattern.compile("<img\\s+src\\s*=\\s*\"?(.*?)[\"|>]",Pattern.CASE_INSENSITIVE);  
262.    Matcher m = p.matcher(pageContents);  
263.      
264.    ArrayList< String> linkList = new ArrayList< String>();  
265.    while (m.find()) {  
266.      String link = m.group(1).trim();  
267.        
268.      if (link.length() < 1) {  
269.        continue;  
270.      }  
271.      // 跳过链到本页面内链接。  
272.      if (link.charAt(0) == '#') {  
273.        continue;  
274.      }  
275.        
276.      if (link.indexOf("mailto:") != -1) {  
277.        continue;  
278.      }  
279.       
280.      if (link.toLowerCase().indexOf("javascript") != -1) {  
281.        continue;  
282.      }  
283.      if (link.toLowerCase().endsWith("gif")) {  
284.          continue;  
285.        }  
286.      if (link.indexOf("://") == -1)  
287.      {  
288.        if (link.charAt(0) == '/')   
289.        {//处理绝对地    
290.          link = "http://" + pageUrl.getHost()+":"+pageUrl.getPort()+ link;  
291.        }   
292.        else   
293.        {           
294.          String file = pageUrl.getFile();  
295.          if (file.indexOf('/') == -1) {//处理相对地址  
296.            link = "http://" + pageUrl.getHost()+":"+pageUrl.getPort() + "/" + link;  
297.          } else {  
298.            String path =file.substring(0, file.lastIndexOf('/') + 1);  
299.            link = "http://" + pageUrl.getHost() +":"+pageUrl.getPort()+ path + link;  
300.          }  
301.        }  
302.      }  
303.      int index = link.indexOf('#');  
304.      if (index != -1) {  
305.        link = link.substring(0, index);  
306.      }  
307.      link = removeWwwFromUrl(link);  
308.      URL verifiedLink = verifyUrl(link);  
309.      if (verifiedLink == null) {  
310.        continue;  
311.      }  
312.      /* 如果限定主机,排除那些不合条件的URL*/ 
313.      if (limitHost &&  
314.          !pageUrl.getHost().toLowerCase().equals(  
315.            verifiedLink.getHost().toLowerCase()))  
316.      {  
317.        continue;  
318.      }  
319.      // 跳过那些已经处理的链接.  
320.//      if (crawledList.contains(link)) {  
321.//        continue;  
322.//      }  
323.      if(filterImg.contains(link))  
324.      {  
325.          logEvent("图片匹配了:"+link);  
326.          continue;  
327.      }  
328.      else 
329.      {  
330.          filterImg.add(link);  
331.      }  
332.        
333.        
334.      if(link.lastIndexOf(".gif")==-1)  
335.      {  
336.          linkList.add(link);  
337.      }  
338.        
339.        
340.         
341.    }  
342.   return (linkList);  
343.  }  
344.   
345.    //执行实际的搜索操作  
346.    public ArrayList< String> crawl(String startUrl,boolean limithost,boolean caseSensitive )  
347.    {   
348.          
349.        // 从开始URL中移出www  
350.        startUrl = removeWwwFromUrl(startUrl);  
351.      
352.        toCrawlList.add(startUrl);  
353.     
354.        int idxPageParse=0;  
355.        while (toCrawlList.size()>0)   
356.        {  
357.            try 
358.            {  
359.                idxPageParse++;  
360.                // Get URL at bottom of the list.  
361.                String url =  toCrawlList.iterator().next();  
362.                ps.setIntUrl(ps.getIntUrl()+1);  
363.                // Remove URL from the to crawl list.  
364.                toCrawlList.remove(url);  
365.                  
366.                int intRetryPage=0;  
367.                while (sempPage.availablePermits()<=0)   
368.                {  
369.                    System.out.println("暂时没有空闲的网页分析线程,等待3秒再执行...");  
370.                    try {  
371.                        intRetryPage++;  
372.                        if(intRetryPage==10)  
373.                        {  
374.                            logEvent("分析网页"+url+"超时");  
375.                            sempPage.release();  
376.                            break;  
377.                        }  
378.                        Thread.sleep(3000);  
379.                    } catch (InterruptedException e) {  
380.                        e.printStackTrace();  
381.                    }  
382.                }  
383.                  
384.                  
385.                ParsePage tempPageThread=new ParsePage(url);  
386.                execPage.submit(tempPageThread);   
387.                logEvent("开启网页分析线程"+idxPageParse);  
388.                if(idxPageParse==1)  
389.                {  
390.                    Thread.currentThread().sleep(30000);  
391.                }  
392.                  
393.            }catch(Exception e)  
394.            {  
395.                e.printStackTrace();  
396.            }  
397.      
398.        }  
399.        blnFlag=false;  
400.     
401.        logEvent("抓图完成......");  
402.      
403.        return result;  
404.    }  
405.  public static  void logEvent(String strLog)  
406.  {  
407.      System.out.println( new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒").format(new Date(Calendar.getInstance().getTimeInMillis()))+"=====>"+strLog);  
408.         
409.  }  
410.    
411.  // 主函数  
412.  public static void main(String[] args) {  
413.     if(args.length!=6)  
414.     {  
415.        System.out.println("Usage:java SearchCrawler startUrl maxUrl searchString");  
416.        return;  
417.     }  
418.    @SuppressWarnings("unused")  
419.    String strLogPath=args[1];  
420.    SearchCrawler crawler = new SearchCrawler(args[0]);  
421.      
422.      
423.    outdir=args[3]+"/pic"+new SimpleDateFormat("yyyyMMdd").format(new Date(Calendar.getInstance().getTimeInMillis()))+"/";  
424.    File f=new File(outdir);  
425.    if(!f.exists())  
426.    {  
427.        f.mkdir();  
428.    }  
429.      
430.    execPage   =   Executors.newFixedThreadPool(30);  
431.    execImg   =   Executors.newFixedThreadPool(300);  
432.    
433.    seroutdir=args[4];  
434.    seroutdirimg=args[5];  
435.      
436.    ps=new PoCalSearch();  
437.    pd=new PoDownload();  
438.    try {  
439.        if(UtilSeriz.readObject(seroutdir)!=null)  
440.        {  
441.            System.out.println(new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒").format(new Date(Calendar.getInstance().getTimeInMillis()))+"=====>"+"反序列化URL...");  
442.            filterUrl=(SimpleBloomFilter)UtilSeriz.readObject(seroutdir);  
443.        }  
444.        else 
445.        {  
446.            filterUrl=new SimpleBloomFilter();  
447.        }  
448.        if(UtilSeriz.readObject(seroutdir)!=null)  
449.        {  
450.            System.out.println(new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒").format(new Date(Calendar.getInstance().getTimeInMillis()))+"=====>"+"反序列化图片...");  
451.              
452.            filterImg=(SimpleBloomFilter)UtilSeriz.readObject(seroutdirimg);  
453.        }  
454.        else 
455.        {  
456.            filterImg=new SimpleBloomFilter();  
457.        }  
458.    } catch (Exception e) {  
459.        e.printStackTrace();  
460.    }  
461.      
462.    String strPic=args[3]+"/pic"+new SimpleDateFormat("yyyyMMdd").format(new Date(Calendar.getInstance().getTimeInMillis()))+".log";  
463.    try {  
464.        bw=new BufferedWriter(new FileWriter(strPic,false));  
465.    } catch (IOException e) {  
466.        // TODO Auto-generated catch block  
467.        e.printStackTrace();  
468.    }    
469.      
470.    Thread  search=new Thread(crawler);  
471.    System.out.println( new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒").format(new Date(Calendar.getInstance().getTimeInMillis()))+"=====>"+"开始爬图...");  
472.    System.out.println("下载了图:");  
473.    search.start();  
474.    try {  
475.        search.join();  
476.        logEvent("主函数结束");  
477.        bw.close();  
478.    } catch (Exception e) {  
479.        // TODO Auto-generated catch block  
480.        e.printStackTrace();  
481.    }  
482.    
483.      
484.      
485.     
486.  }  
487.    
488.  /** 
489.   * 说明:下载图片的线程 
490.   * @author binbin0915 
491.   * 
492.   */ 
493.  public class ImgDownThread implements Runnable,Callable<Long>{  
494.      //待下载的URL   
495.      private String stru;  
496.          
497.        private boolean isStart=true;  
498.          
499.        public ImgDownThread(String strurl) {  
500.            super();  
501.            this.stru = strurl;  
502.        }  
503.          
504.        @Override 
505.        public void run()   
506.        {  
507.              
508.              
509.            try   
510.            {  
511.                    sempImg.acquire();  
512.                    try{  
513.                      
514.                      
515.                    URL url=new URL(stru);  
516.                    BufferedInputStream  in = new BufferedInputStream(url.openStream());  
517.      
518.                    BufferedImage bi=ImageIO.read(url.openStream());     
519.                          
520.                    //尺寸要求  
521.                    if (bi==null|| bi.getWidth()<30 || bi.getHeight()<30  )  
522.                    {  
523.          
524.                        in.close();  
525.                        return;  
526.                    }  
527.                    String ss=new SimpleDateFormat("yyyyMMddHHmmss").format(new Date(Calendar.getInstance().getTimeInMillis()))+"_"+Math.round(Math.random()*89999999999999L+1000)+stru.substring(stru.lastIndexOf("."));  
528.                    String s=outdir+ss;  
529.                    FileOutputStream   file = new FileOutputStream(new File(s));  
530.                    int t;  
531.                    while ((t = in.read()) != -1)   
532.                    {  
533.                        file.write(t);  
534.                    }  
535.                    file.close();  
536.                    if(new File(s).length()<=10*1024)  
537.                    {  
538.                          
539.                        in.close();  
540.                        new File(s).delete();  
541.                        return;  
542.                    }  
543.                      
544.                    synchronized(bw)  
545.                    {  
546.                        String str=ss+":"+stru;  
547.                        bw.write(str);  
548.                        bw.newLine();  
549.                        bw.flush();  
550.                    }  
551.                    logEvent("下载了:"+stru);  
552.                    ps.setIntImg(ps.getIntImg()+1);  
553.                    in.close();  
554.                      
555.                    }catch(Exception e){  
556.                         logEvent("**********************下载图片:"+stru+"超时");  
557.                    }  
558.            }  
559.                  
560.              
561.            catch (Exception e)   
562.            {  
563.                  
564.                e.printStackTrace();  
565.            }  
566.            finally{  
567.                sempImg.release();  
568.            }  
569.              
570.        }  
571. 
572.      
573.        public boolean isStart() {  
574.            return isStart;  
575.        }  
576. 
577.        public void setStart(boolean isStart) {  
578.            this.isStart = isStart;  
579.        }  
580. 
581.        @Override 
582.        public Long call() throws Exception {  
583.            try   
584.            {  
585.                    sempImg.acquire();  
586.                    try{  
587.                      
588.                      
589.                    URL url=new URL(stru);  
590.                    BufferedInputStream  in = new BufferedInputStream(url.openStream());  
591.      
592.                    BufferedImage bi=ImageIO.read(url.openStream());     
593.                          
594.                    //尺寸要求  
595.                    if (bi==null|| bi.getWidth()<30 || bi.getHeight()<30  )  
596.                    {  
597.          
598.                        in.close();  
599.                        return 0l;  
600.                    }  
601.                    String ss=new SimpleDateFormat("yyyyMMddHHmmss").format(new Date(Calendar.getInstance().getTimeInMillis()))+"_"+Math.round(Math.random()*89999999999999L+1000)+stru.substring(stru.lastIndexOf("."));  
602.                    String s=outdir+ss;  
603.                    FileOutputStream   file = new FileOutputStream(new File(s));  
604.                    int t;  
605.                    while ((t = in.read()) != -1)   
606.                    {  
607.                        file.write(t);  
608.                    }  
609.                    file.close();  
610.                    if(new File(s).length()<=10*1024)  
611.                    {  
612.                          
613.                        in.close();  
614.                        new File(s).delete();  
615.                        return 0l;  
616.                    }  
617.                      
618.                    logEvent("下载了:"+stru);  
619.                    ps.setIntImg(ps.getIntImg()+1);  
620.                    in.close();  
621.                      
622.                    }catch(Exception e){  
623.                         logEvent("**********************下载图片:"+stru+"超时");  
624.                    }  
625.            }  
626.                  
627.              
628.            catch (Exception e)   
629.            {  
630.                  
631.                e.printStackTrace();  
632.            }  
633.            finally{  
634.                sempImg.release();  
635.                return 1l;  
636.            }  
637.              
638.        }  
639.        
640.  }  
641.    
642.  /*** 
643.   * 序列化已访问的URL 
644.   * @author binbin0915 
645.   * 
646.   */ 
647.  public class TimeWrite2File implements Runnable  
648.  {  
649.      @Override 
650.      public void run()   
651.      {  
652.          while(blnFlag)  
653.          {  
654.              try   
655.              {  
656.                   
657.                  synchronized(ps)  
658.                  {  
659.                      logEvent("开始序列化URL");  
660.                      UtilSeriz.writeObject(filterUrl,seroutdir);  
661.                      logEvent("结束序列化URL");  
662.                      logEvent("开始序列化图片");  
663.                      UtilSeriz.writeObject(filterImg,seroutdirimg);  
664.                      logEvent("结束序列化图片");  
665.                      logEvent("分析了"+ps.getIntUrl()+"个链接");  
666.                      logEvent("下载了"+ps.getIntImg()+"张图片");  
667.                  }  
668.                      Thread.sleep(600000);  
669.                    
670.              }  
671.              catch (Exception e)   
672.              {  
673.                  e.printStackTrace();  
674.              }  
675.              
676.          }  
677.          
678.      }  
679.        
680.    }  
681.      
682.    
683.    /*** 
684.     * 分析对应URL网页的线程 
685.     * @author Administrator 
686.     * 
687.     */ 
688.    class ParsePage extends Thread  
689.    {  
690.          
691.        String url;  
692.        int iCount=0;  
693.          
694.        public int getiCount() {  
695.            return iCount;  
696.        }  
697.        public void setiCount(int iCount) {  
698.            this.iCount = iCount;  
699.        }  
700.        public String getUrl()   
701.        {  
702.            return url;  
703.        }  
704.        public void setUrl(String url)  
705.        {  
706.            this.url = url;  
707.        }  
708.        public ParsePage(String url) {  
709.            this.url=url;  
710.        }  
711.        @Override 
712.        public void run()   
713.        {  
714.            try 
715.            {  
716.                sempPage.acquire();  
717.                // Convert string url to URL object.  
718.                URL verifiedUrl = verifyUrl(url);  
719.      
720.                // Skip URL if robots are not allowed to access it.  
721.                if (!isRobotAllowed(verifiedUrl))  
722.                {  
723.                    Thread.currentThread().stop();  
724.                }  
725.      
726.        
727.                // 增加已处理的URL到crawledList  
728.                String pageContents="";  
729.                  
730.                pageContents = downloadPage(verifiedUrl);  
731.          
732.                logEvent("分析了:"+verifiedUrl);  
733.                logEvent("待分析URL数:"+toCrawlList.size()+"个");  
734.                  
735.                  
736.                if (pageContents != null && pageContents.length() > 0)  
737.                {  
738.                    // 从页面中获取有效的链接  
739.                    ArrayList< String> links =retrieveLinks(verifiedUrl, pageContents,limitHost);  
740.          
741.                    // 从页面中获取有效的链接  
742.                    ArrayList< String> imglinks =retrieveImgLinks(verifiedUrl, pageContents,limitHost);  
743.          
744.                    //添加到图片下载队列  
745.                    if(toCrawlList.size()<100000)  
746.                    {  
747.                        toCrawlList.addAll(links);  
748.                    }  
749.                    else 
750.                    {  
751.                        logEvent("待分析的网页URL超过100000!!!!跳过.......");  
752.                    }  
753.                      
754.          
755.                      
756.                    for(int i=0;i<imglinks.size();i++)  
757.                    {  
758.                        if(imglinks.get(i).indexOf("http:")!=-1)  
759.                        {  
760.      
761.                            iCount++;  
762.                            filterImg.add(imglinks.get(i));  
763.                            ps.setIntImg(ps.getIntImg()+1);  
764.                          
765.                          
766.                            int intRetryImg=0;  
767.                            while (sempImg.availablePermits() <= 0)   
768.                            {  
769.                                System.out.println("暂时没有空闲的抓图线程,等待3秒再执行...");  
770.                                try {  
771.                                    intRetryImg++;  
772.                                    if(intRetryImg==10)  
773.                                    {  
774.                                        logEvent("抓图"+imglinks.get(i)+"超时");  
775.                                        sempImg.release();  
776.                                    }  
777.                                    Thread.sleep(3000);  
778.                                } catch (InterruptedException e) {  
779.                                    e.printStackTrace();  
780.                                }  
781.                            }  
782.                            Thread tempImgThread=new Thread(new ImgDownThread(imglinks.get(i)));  
783.                            execImg.submit(tempImgThread);   
784.                          
785.                            if((iCount!=1) && (iCount%10==1) )  
786.                            {  
787.                                try   
788.                                {  
789.                                    logEvent("图多休息2秒......");  
790.                                    Thread.currentThread().sleep(2000);  
791.                                }  
792.                                catch (InterruptedException e)   
793.                                {  
794.                                    e.printStackTrace();  
795.                                }  
796.                            }  
797.                  
798.                  
799.                        }  
800.              
801.                    }  
802.                }  
803.                synchronized(arrPar)  
804.                {  
805.                    arrPar.remove(this);  
806.                }  
807.            }  
808.            catch(Exception e)  
809.            {  
810.                e.printStackTrace();  
811.                  
812.            }  
813.            finally 
814.            {  
815.                sempPage.release();  
816.            }  
817.        }  
818.        
819.    }  
820.} 


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/binyao02123202/archive/2010/07/17/5741519.aspx
分享到:
评论

相关推荐

    抓图程序 JAVA版 用JAVA写的抓图程序

    总的来说,这个Java抓图程序涵盖了网络编程、HTML解析、文件操作等多个核心Java技术,对于学习和提升Java开发技能非常有帮助。通过阅读和理解源代码,开发者可以深入理解这些概念并应用到自己的项目中。

    抓图程序 JAVA版的教学PPT

    【描述】:“这是对上一个资源JAVA抓图程序的PPT说明,格式是PPTX,如果学习的话可以下载来看看。” 这份教学PPT是基于之前发布的JAVA抓图程序资源的补充说明,采用PPTX格式,便于理解和学习。通过下载和学习,你...

    JAVA屏幕抓图(源码)

    在Java编程语言中,实现屏幕抓图功能是一项常见的任务,特别是在开发桌面应用或者需要进行自动化测试时。这个项目提供了一段源码,模仿了QQ截图的功能,允许用户通过拖动鼠标来选择屏幕上的任何区域进行截图,并且...

    屏幕抓图程序

    总结来说,构建一个屏幕抓图程序需要对Java GUI编程有深入理解,包括`java.awt`包下的各种类和接口。同时,还需要熟悉系统级交互和多线程编程,以实现更复杂的特性和功能。通过不断的实践和学习,开发者可以创建出...

    用java实现的网页抓图,下载自己喜欢的图片

    本项目利用Java实现了一种网页抓图的功能,允许用户下载他们喜欢的网页图片。下面将详细介绍这个过程涉及的技术点和实现方法。 首先,我们要理解网页抓图的基本原理。网页抓图,也称为网页截图或网页快照,是指获取...

    屏幕抓图小程序(完整及代码全)

    在开发屏幕抓图程序时,通常会涉及到以下几个关键知识点: 1. 图像处理库:为了读取、处理和保存屏幕截图,开发者通常会利用图像处理库,如Python的PIL(Python Imaging Library)或C#的System.Drawing命名空间。...

    Java对接大华摄像头进行抓图和录像的demo

    为了实现远程操作,Java程序需要与摄像头建立网络连接。这可能涉及到TCP/IP、UDP或其他特定的通信协议。大华摄像头可能支持RTSP (Real-Time Streaming Protocol) 或ONVIF (Open Network Video Interface Forum) ...

    JAVA实现屏幕抓图 远程桌面控制

    ### JAVA实现屏幕抓图与远程桌面控制 #### 一、Java屏幕抓图技术解析 在Java中,要实现屏幕抓图的功能,主要依赖于`java.awt.Robot`类。该类提供了一系列方法来模拟键盘和鼠标操作,并允许开发人员捕获整个屏幕或...

    一个简单的用JAVA实现的屏幕抓图(源代码)

    根据给定的文件信息,我们可以总结出以下关于使用Java...通过掌握这些基本原理,开发者可以轻松地在Java应用程序中集成屏幕抓图功能,无论是为了开发测试工具、图像处理软件还是任何其他需要屏幕捕获功能的应用程序。

    商业编程-源码-抓图程序开发实践配套源代码.zip

    通过分析和研究这些源代码,我们可以了解到抓图程序的实现机制,以下是一些相关的知识点: 1. 图像捕获技术:抓图程序的核心功能是捕捉屏幕上的图像。这涉及到操作系统级别的API调用,例如Windows平台的GDI或GDI+库...

    大华摄像头抓图录像亲测可用

    4. **JNA库的使用**:解释如何利用Java Native Access库在Java程序中直接调用摄像头的API,实现对摄像头的控制。 5. **实战示例**:“JNADemo”可能提供了一个具体的代码实例,展示如何通过编程实现抓图和录像功能...

    Java海康威视网络摄像机和NVR录像机的SDK二次开发,实现对网络摄像机/NVR的实时流、历史流的推流功能以及抓图、录像下载等

    在本文中,我们将深入探讨如何使用Java进行海康威视(Hikvision)网络摄像机和NVR录像机的SDK...开发者需要深入理解SDK的使用,结合Java语言特性,构建稳定、高效的应用程序,以实现对网络摄像机/NVR的全面控制和管理。

    java 屏幕抓图 源代码

    MyEclipse提供了编写、编译、调试Java应用程序的功能,包括屏幕抓图的应用。 7. **源代码结构**: 压缩包中的"ScreenCapture"可能是一个Java源文件,包含了实现屏幕抓图功能的主要代码。通常,它会包含一个主类,...

    基于OpenCV+VC编写的抓图程序

    综上所述,这个基于OpenCV和VC++的抓图程序是一个全面的解决方案,它涵盖了实时视频显示、抓图、视频录制以及对已有视频的处理,且允许用户根据自己的需求调整抓图参数。对于学习计算机视觉或进行相关项目开发的人员...

    大华java开发文档

    大华摄像头sdk开发文档和java版本的demo.4、 demo路径: 考勤机:src\main\java\com\netsdk\demo\frame\Attendance ... 以上是功能的界面实现,接口实现路径:src\main\java\com\netsdk\demo\module\

    使用海康sdk实现了实时预览,历史回放和云台控制的java spring-boot程序.zip

    如果您下载了本程序,但是该程序存在问题无法运行,那么您可以选择退款或者寻求我们的帮助(如果找我们帮助的话,是需要追加额外费用的)。另外,您不会使用资源的话(这种情况不支持退款),也可以找我们帮助(需要...

    String boot 整合海康SDK 常用功能 实时预览,设备抓图,云台反向定位,云台旋转控制,获取云台参数

    在本文中,我们将深入探讨如何使用String Boot整合海康威视(Hikvision)的SDK,实现一系列关键功能,包括实时预览、设备抓图、云台反向定位、云台旋转控制以及获取云台参数。这些功能对于构建监控系统或者进行远程...

    基于海康sdk的java程序摄像头实时抓拍图片保存到本地.zip

    标题中的“基于海康sdk的java程序摄像头实时抓拍图片保存到本地”表明这是一个使用海康威视(Hikvision)提供的SDK进行Java编程的项目,目的是实现通过摄像头实时捕获图像并将其保存到本地计算机的功能。这个项目是...

    Java-Swing界面的摄像头\\高拍仪抓图功能,有预览视频-使用xuggle。

    在Java Swing中实现摄像头或高拍仪的抓图功能,可以极大地增强应用的交互性和实用性。本教程将深入探讨如何利用Xuggler库来实现在Java Swing界面上进行摄像头预览和抓图。 首先,Xuggler是一个开源的Java库,主要...

    java程序设计实验报告格式

    这部分要详细描述本次实验的目标和内容,包括要实现的功能、涉及的编程概念和技术,例如:设计一个简单的控制台应用程序,实现字符串操作,或者使用面向对象编程设计一个类结构。 4. **实验程序清单** 提供实验...

Global site tag (gtag.js) - Google Analytics