Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 327|回复: 0

[网络编程学习]网站图片下载器(JAVA)

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-3 00:02:01 | 显示全部楼层 |阅读模式
    功能:给定一URL,自动搜索页面下的图片,遇到url自动记录,下载图片,重复N层,退出。 HTTP.java:主要代码和逻辑都在这个里头,DOWNPIC是负责下载图片的,呵呵,用了十个线程并发去跑。

    1. 一:记录URL及它所处的层次
    2. public class URLObj  
    3. {  
    4.     private String  urlString = null;  
    5.     private int index = -1;  
    6.       
    7.     public URLObj(String url , int index)  
    8.     {  
    9.         this.urlString = url;  
    10.         this.index = index;  
    11.     }  
    12.    
    13.     public String getUrlString(){
    14.        return urlString;
    15.     }
    16.     public int getIndex(){
    17.       return index;
    18.     }
    19.     public void setUrlString(String urlString){
    20.        this.urlString=urlString;
    21.     }
    22.     public void setIndex(int index){
    23.       this.index=index;
    24.     }
    25. }
    26. 二、根据图片的绝对URL地址下载该图片
    27. import java.net.MalformedURLException;
    28. import java.net.URL;
    29. import java.io.*;
    30.   
    31. public class URLDownPic  
    32. {  
    33.     URL url;  
    34.   
    35.     public void down(String imgUrl)  
    36.     {  
    37.            System.out.println("down......"+imgUrl);
    38.            String fileName = imgUrl.substring(imgUrl.lastIndexOf("/")+1,imgUrl.length());  
    39.             try {
    40.                url = new URL(imgUrl);
    41.             } catch (MalformedURLException e) {
    42.                  System.out.println(imgUrl+"异常,无法下载");
    43.                  e.printStackTrace();
    44.             }
    45.          
    46.              InputStream is = null;
    47.             try {
    48.               is = url.openStream();
    49.             }catch (IOException e) {
    50.                e.printStackTrace();
    51.                System.out.println(imgUrl+"没有下载成功1");
    52.                return;
    53.             }
    54.               OutputStream os = null;
    55.              File f = new File("c:\webimg");
    56.              f.mkdirs();
    57.              try{
    58.                os = new FileOutputStream("c:\webimg"+fileName);
    59.                int bytesRead = 0;
    60.                byte[] buffer = new byte[8192];
    61.                while((bytesRead = is.read(buffer,0,8192))!=-1){
    62.                    os.write(buffer,0,bytesRead);
    63.                }
    64.             }catch(FileNotFoundException e){
    65.               e.printStackTrace();
    66.               System.out.println(imgUrl+"没有下载成功2");
    67.             } catch(IOException e) {
    68.                e.printStackTrace();
    69.               System.out.println(imgUrl+"没有下载成功3");
    70.             }
    71.          
    72.      }
    73.       public static void main(String args[]){
    74.            new URLDownPic().down("http://www.baidu.com/logo.gif");
    75.       }
    76.      
    77. }
    78. 三、处理主要逻辑,打开一个网页,提取里面和网址和图片地址等
    79. import java.io.BufferedReader;  
    80. import java.io.InputStreamReader;  
    81. import java.net.URL;  
    82. import java.net.URI;
    83. import java.net.MalformedURLException;
    84. import java.net.URISyntaxException;
    85. import java.net.URLConnection;  
    86. import java.util.ArrayList;  
    87. import java.util.HashSet;  
    88. import java.util.Iterator;  
    89. import java.util.regex.Matcher;  
    90. import java.util.regex.Pattern;  
    91.   
    92. public class HTTP implements Runnable  
    93. {  
    94.     StringBuffer textStringBuffer;  
    95.     public static HashSet
    96.    
    97.       allUrlSet;  //这两个hashSet是作为是否有重复URL检测用  
    98.     public static HashSet
    99.      
    100.        allPicSet;  
    101.       
    102.     public static ArrayList
    103.       
    104.         allUrList;  //全局变量
    105.       
    106.     HashSet
    107.       
    108.          curPagePicSet;  //当前页面的图片
    109.       
    110.     //正则表达式,前半是网址,后半是JPG图像,两者得其一就是匹配,
    111.     //这个正则只提取单引号或双引号中的图片或网址链接,网上有好些的,可以改进。
    112.     String patternStrs=
    113.    "(< a\s*href=[""](.*?)[""].*?>)|(?:(src|SRC|background|BACKGROUND)=[""](.*?)[""].*?>)";   

    114.     public String urlString =null;  
    115.       
    116.     URLDownPic downPic= null;  //下载工具类
    117.       
    118.     /** 搜索的深度,如果为1就只搜索当前页面的所有图片 */  
    119.     public static int searchDepth = 1;  
    120.       
    121.     /** 线程如果发现没有队列中没有URL,就睡眠一次,睡N次后,就中止线程 */  
    122.     int sleepTimes = 0;  
    123.     int sleepMaxTime = 10;  
    124.       
    125.     public HTTP(String url)  //构造函数
    126.     {  
    127.         this();
    128.         urlString = url;  
    129.     }  
    130.       
    131.     public HTTP()  
    132.     {  
    133.         downPic = new URLDownPic();  
    134.         textStringBuffer = new StringBuffer();  
    135.         if (allUrlSet== null)  
    136.         {  
    137.             allUrlSet = new HashSet< String>();  
    138.         }  
    139.         if (allPicSet == null)  
    140.         {  
    141.             allPicSet = new HashSet< String>();  
    142.         }  
    143.         if (allUrList ==null)  
    144.         {  
    145.             allUrList = new ArrayList< URLObj>();  
    146.         }  
    147.         curPagePicSet = new HashSet< String>();  
    148.     }  
    149.   public  String getAbsoluteURL(String baseURI, String relativePath){ //由相对URL,得到绝对URL
    150.     //System.out.println("baseURI="+baseURI);
    151.    //System.out.println("相对路径="+relativePath);
    152.     String abURL=null;   
    153.     try {   
    154.         URI base=new URI(baseURI);//如:baseURI="http://hi.baidu.com/zeiysiufehbbeqq/"
    155.         URI abs=base.resolve(relativePath);//解析网页的相对URL,得到绝对URI   
    156.         URL absURL=abs.toURL();//转成URL   
    157.         //System.out.println(absURL);   
    158.         abURL = absURL.toString();   
    159.     } catch (MalformedURLException e) {  
    160.         System.out.println("相对路径转绝对路径时出错1!");
    161.         e.printStackTrace();   
    162.     } catch (URISyntaxException e) {   
    163.         e.printStackTrace();   
    164.         System.out.println("相对路径转绝对路径时出错2!");
    165.     } finally{   
    166.         return abURL;   
    167.     }   
    168. }  
    169. public String getText(String url)  
    170.     {  
    171.         // System.out.println("处理文本="+url);
    172.         try  
    173.         {  
    174.             String urlName = url;  
    175.             URL U = new URL(urlName);  
    176.               
    177.             URLConnection connection = U.openConnection();  
    178.             connection.setConnectTimeout(2000);  
    179.             connection.connect();  
    180.   
    181.             BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));  
    182.             String line;  
    183.             while ((line = in.readLine()) != null)  
    184.             {  
    185.                 textStringBuffer.append(line);  
    186.             
    187.             }  
    188.               
    189.             in.close();  
    190.             return textStringBuffer.toString();  
    191.         }   
    192.         catch (Exception e)  
    193.         {  
    194.             System.out.println("从"+url+"处获取文本没有结果!");  
    195.             e.printStackTrace();  
    196.         }  
    197.         return null;  
    198.     }  

    199.    public static String getBaseURI(URLObj urlObj){
    200.                
    201.          String urlString=urlObj.getUrlString();
    202.          int i=urlString.lastIndexOf("/");
    203.          if(i==6) return urlString+"/";
    204.          else
    205.           return urlString.substring(0,i+1);
    206.      }
    207.       
    208.     public void go(URLObj urlObj)  

    209.     {  
    210.           System.out.println("处理网页="+urlObj.getUrlString());
    211.         //得到当前网页的baseURI
    212.         String baseURI=getBaseURI(urlObj);
    213.    
    214.         //根据url得到HTTP流  
    215.         String httpString = getText(urlObj.getUrlString());  
    216.                
    217.         //跟据正则表达式获得网址,一类是图片,一类是网页网址,递归找啊!  
    218.         Pattern p=Pattern.compile(patternStrs);  
    219.         if (p == null)  //没有找到就返回  
    220.         {  
    221.             return;  
    222.         }  
    223.         Matcher m=p.matcher(httpString);  
    224.          
    225.         while (m!=null && m.find())  
    226.         {  
    227.             //找到的有可能是重复的,有可能是别的网页已经下过的,就跳过,
    228.           //否则加入HASHSET,下面进行下载和递归搜索  
    229.             byte stringType=-1; //该字符串种类,1是网页URL,2是JPG图片  
    230.             String tempS = null;  
    231.             if (m.group(2)!=null)   //这个是URL  
    232.             {  
    233.                 tempS= m.group(2);  
    234.                //这里只搜索下面这些扩展名结尾的,省略了好多,
    235.               //用网址直接给出的图片也省了,如: href="http://www.baidu.com/aa/1.gif"之类
    236.            if(!tempS.matches(".*(?i)(\.(cn)$|\.(com)$|\.(net)$|\.(org)$|\.(htm)$|
    237.                  \.(html)$|\.(jsp)$|\.(asp)$|\.(php)$|\.(aspx)$)"))
    238.                   continue;
    239.                 stringType = 1;  
    240.                
    241.             }  
    242.             else   
    243.             {  
    244.                 tempS= m.group(4);  
    245.                //只下载下面扩展名结尾的
    246.               if(!tempS.matches(".*(?i)(\.(gif)$|\.(jpg)$|\.(png)$|\.(jpeg)$|\.(bmp)$)"))
    247.                   continue;
    248.                 stringType = 2;  
    249.                
    250.             }
    251.          
    252.            //如果是相对路径就转成绝对路径  
    253.             if (!tempS.startsWith("http"))  
    254.             {  
    255.             
    256.                 tempS = getAbsoluteURL(baseURI,tempS);
    257.             }
    258.             // System.out.println("找到="+tempS);
    259.            switch (stringType)  
    260.             {  
    261.             case 1:  
    262.                 if (allUrlSet.contains(tempS))  //判断是否登录过此网页
    263.                     continue;  
    264.                 if (urlObj.getIndex()>searchDepth)   //是否超过了应爬的深度   
    265.                     continue;  
    266.               
    267.                 //加锁,防止添加时有别的线程删除  
    268.                 synchronized (allUrList)  
    269.                 {  
    270.                     allUrList.add(new URLObj(tempS,urlObj.getIndex()+1));  
    271.                 }  
    272.                  allUrlSet.add(tempS);  //记录此页面已登记过
    273.                 break;  
    274.             case 2:  
    275.                 if (!allPicSet.contains(tempS))  
    276.                 {  
    277.                     curPagePicSet.add(tempS);  
    278.                     allPicSet.add(tempS);  
    279.                 }  
    280.                 break;  
    281.             default:  
    282.                 break;  
    283.             }  
    284.   
    285.          
    286.         }  
    287.          
    288.         //疯狂下图。。。  
    289.         Iterator
    290.         
    291.           iterator = curPagePicSet.iterator();  
    292.         while (iterator.hasNext())  
    293.         {  
    294.             String imgUrl = iterator.next();  
    295.             downPic.down(imgUrl);  
    296.         }  
    297.          
    298.          
    299.     }  
    300.       
    301.       
    302.     @Override  
    303.     public void run()  
    304.     {  
    305.         boolean isHasNewUrl = false;  
    306.          
    307.         while (true)  
    308.         {  
    309.             try  
    310.             {  
    311.                 if (allUrList.size()>0)  
    312.                 {  
    313.                     URLObj urlObj = null;  
    314.                     synchronized (allUrList)  
    315.                     {  
    316.                         if (allUrList.size()>0)  
    317.                         {  
    318.                             urlObj = allUrList.get(0);  
    319.                             allUrList.remove(0);  
    320.                             isHasNewUrl= true;  
    321.                         }  
    322.                     }  
    323.                     if (isHasNewUrl)  
    324.                     {  
    325.                         go(urlObj);  
    326.                     }  
    327.                 }  
    328.                 else   
    329.                 {  
    330.                     Thread.sleep(500);  
    331.                     sleepTimes++;  
    332.                     if (sleepTimes>sleepMaxTime)  
    333.                     {  
    334.                         break;  
    335.                     }  
    336.                 }  
    337.             }  
    338.             catch (Exception e)  
    339.             {  
    340.                 System.out.println("线程运行时发生错误");
    341.                 e.printStackTrace();  
    342.             }  
    343.         }  
    344.          
    345.          
    346.     }  
    347.       
    348.     public static void main(String args[])  
    349.     {  
    350.         String urlString ="http://www.baidu.com";//必须以http打头
    351.         allUrList = new ArrayList< URLObj>();  //将要爬的网页放在这里,绝对地址
    352.         allUrlSet = new HashSet< String>();  
    353.         allUrList.add(new URLObj(urlString,1));  
    354.         allUrlSet.add(urlString);  //已经爬过的网页放在这里
    355.          
    356.         Thread[] http = new Thread[10];  
    357.          
    358.         for (int i = 0; i < http.length; i++)  
    359.         {  
    360.             http[i] = new Thread(new HTTP());  
    361.             http[i].start();  
    362.         }  
    363.     }  
    364.   
    365. }
    366.         
    367.       
    368.       
    369.      
    370.    
    复制代码


       
         
         
          
          

            
          

            
          
         
       

      


    源码下载:http://file.javaxxz.com/2014/11/3/000200859.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-11-12 20:07 , Processed in 0.473376 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表