给个需要:通过HTTP协定来获取指定网页的图片,并下载到本地,且用照片的名字来命名照片。这里我就拿学校的官网来作为指定网页,来实现下载官网图片的性能。
至于如何用HTTP协定制作一个繁难的客户端,能够参考我之前写的一篇文章:
手写一个繁难的安卓客户端:https://segmentfault.com/a/1190000043478702


如何获取官网上的图片信息。首先咱们要晓得,咱们该如何获取网页上的图片信息。咱们通过申请服务器展现图片的网页的相干门路,服务器就会返回一个HTML页面的响应。而这个HTML页面里就有许许多多的<img>标签,图片的相干信息就寄存在这个标签之中。以我学校的官网举例:

所以咱们要做的事件就是利用正则表达式来提取HTML页面中<img>标签。

1、创立一个繁难的http客户端类,连贯到指定的服务端

public class Client {    private int port = 80 ;//这个是http协定的默认端口号    private String host = "指定网页的近程地址";    String url;    public Client(){    }    public Client(int port,String host){        this.port = port;        this.host = host;    }    public void clientServer() throws IOException{        System.out.println("连贯上服务器");        Socket socket = new Socket(host, port);    }    public void writeToServerGET(OutputStream clientOut,String url ,String host,int port) throws IOException {        clientOut.write(("GET" +" "+url+" "+"HTTP/1.1"+"\r\n").getBytes());        clientOut.write(("Accept:"+" "+"text/html"+"\r\n").getBytes());        clientOut.write(("HOST:"+" "+ host+":"+port+"\r\n").getBytes());        clientOut.write(("Connection: "+"keep-alive"+"\r\n").getBytes());        clientOut.write("\r\n".getBytes());        clientOut.flush();    }     public static void main(String[] args) throws IOException {        new Client().clientServer();    }}

2、在Client类中创立读取输出流的办法readResponse()办法

public String readResponse(BufferedReader bufferedReader) throws IOException {        String RSHttp="";        String str = "";        //将读取到的申请报文按行读取        while ((str=bufferedReader.readLine())!= null){            RSHttp +="\r\n" +str;            System.out.println(str);        }        return RSHttp;    }

**3、给出getMatchStringSrc()办法以及getMatchStringAlt()办法。
咱们要做的就是提取<img>标签中的src、alt**

 public static List<String> getMatchStringAlt(String string){        List<String> alts = new ArrayList<>();        Pattern compile = null ;        compile = Pattern.compile("<img.*?>");        Matcher matcher = compile.matcher(getMatchStringClass(string).toString());//这里调用了getMatchStringClass()办法        while (matcher.find()){            String img = matcher.group();            Matcher m = Pattern.compile("alt\\s*=\\s*\"?\\s*(.*?)(\"|>|\\s+)").matcher(img);            if(m.find()){                String group = null;                group = m.group();                System.out.println(group);                alts.add(group.substring(5,group.length()-1));            }        }        return  alts;    }    public static List<String> getMatchStringSrc( String string){        List<String> pics = new ArrayList<>();        //实例化 compile        Pattern compile = null;        compile = Pattern.compile("<img.*?>");//利用正则表达式来获取到html中指定的标签<img>        //比拟是否寻找到        Matcher matcher = compile.matcher(getMatchStringClass(string).toString());        /*        *尝试查找与模式匹配的输出序列的下一个子序列。         当且仅当输出序列的子序列匹配此匹配器的模式时返回:true        * */        while (matcher.find()) {            String img = matcher.group();            //Matcher得利用Pattern来实例化            Matcher m = Pattern.compile("\"http?(.*?)(\"|>|\\s+)").matcher(img);//利用正则表达式来获取<img>标签中的url            m.find();            //group()前一个匹配以字符串模式匹配的子序列(可能为空,就是没有 find()办法没有找到下一个匹配的子序列时为空)            String group = m.group();            System.out.println(group);            pics.add(group.substring(1, group.length() - 1));        }        return pics;    }

能够看到,我在getMatchStringSrc()办法以及getMatchStringAlt()办法中还调用了一个getMatchStringClass()办法,这是应为在一个网页中有许许多多的图片信息,以我学校的官网举例:

而咱们要获取的只是那些照片信息,所以不能提取所有的<img>,咱们要把合乎需要的<img>提取进去,所以要利用getMatchStringClass()办法,放大提取的范畴

public static List<String> getMatchStringClass(String string){        List<String> names = new ArrayList<>();        Pattern compile = null;        compile =Pattern.compile("<div\\s.*?><img.*?>");        Matcher matcher =compile.matcher(string);        while(matcher.find()){            String div = matcher.group();            Matcher m =Pattern.compile("class\\s*=\\s*\"?(.*?)(\"|>|\\s+)").matcher(div);            m.find();            String group = null;            group = m.group();            if(group.equals("class=\"page_news_lists\"")){//获取class=page_news_lists 的div作为接下来提取<img>标签的范畴                names.add(div);            }        }        return  names;    }

4、进行逻辑解决

public void clientServer() throws IOException{        System.out.println("连贯上服务器");        Socket socket = new Socket(host, port);        //指标门路        url = "/html/cmfy/xiaoyou/";        OutputStream clientOut = socket.getOutputStream();        //发送封装好的申请报文        writeToServerGET(clientOut,url,host,port);        System.out.println("url发送胜利");        //获取字节流        InputStream clientIn = socket.getInputStream();        //转为字符流        BufferedReader buf = new BufferedReader(new InputStreamReader(clientIn,"UTF-8"));        System.out.println("拆解响应内容");        //读取响应的html        String result = readResponse(buf);//调用了readResponse()办法        //将getMatchString()办法返回的图片门路寄存在 picture汇合中        List<String> picture = new ArrayList<>();        picture = getMatchStringSrc(result);//调用了getMatchStringSrc()办法,获取对应图片在网页上的下载门路        int count = picture.size();//汇合的元素个数        System.out.println(count);        List<String> alt = new ArrayList<>();        alt = getMatchStringAlt(result);//调用了getMatchStringAlt()办法,获取对应图片的姓名        int count2 = alt.size();        System.out.println(alt);        //将SRC转化为字符串按','宰割。   这个办法行不通,将汇合转为字符串之后,有一对'[]'解决不了        /*String SRC = picture.toString();        System.out.println(SRC);  */        while(count>0){            //get()返回列表中指定地位的元素。            String name = alt.get(count2-1);            String path = picture.get(count-1);            System.out.println("还剩"+count+"张");            System.out.println(name);            System.out.println(path);            //读取到图片门路后下载            URL url = new URL(path);            DataInputStream dataInputStream = new DataInputStream(url.openStream());            String newImageName="E://picture/"+name +".jpg";//将图片寄存的门路赋值给newImageName            byte[] buffer = new byte[1024];            int length = 0;            //关上指定门路的文件夹 newImageName            FileOutputStream fileOutputStream = new FileOutputStream(new File(newImageName));            //将图片读入fileOutputStream            while((length = dataInputStream.read(buffer))>0){                fileOutputStream.write(buffer,0,length);            }            System.out.println("上传胜利");            dataInputStream.close();            fileOutputStream.close();            count--;            count2--;        }        clientOut.close();        System.out.println("打印实现");    }

执行!

能够看到,图片曾经下载到本地,且以名字作为图片的命名形式。

总结:

1、我通过浏览器申请学校官网,取得了学校官网的近程地址和端口号
2、创立get_Picture我的项目,首先定义一个port和host,创立构造方法Client(),通过构造方法将port和host传入clentServer()办法中的Socket socket = new Socket(host, port);
3、与服务器进行连贯之后,向服务器发送一个Get申请,申请的门路为"/html/cmfy/xiaoyou/",期待服务器响应
4、将服务器响应的内容通过InputStream读取,再通过BufferedReader将读取到的字节流转化为字符流
5、创立一个读取字符流的办法readResponse()进行按行读取。
6、在clientServer()办法中调用readResponse()办法(将获取到的字符流按行打印),并返回给clientServer()
7、创立一个拆解出html中图片地址的办法getMatchString(),返回一个汇合。
8、clientServer()办法获取到readResponse()办法返回String值之后,调用getMatchStringSrc()办法和getMatchStringAlt()办法,将String值作为参数传入到这两给办法之中
9、getMatchStringSrc()办法和getMatchStringAlt()办法中调用getMatchStringClass()办法,来获取指定地区的图片信息
8、在clientServer()办法中创立一个汇合用来贮存getMatchStringSrc()办法和getMatchStringAlt()办法返回的汇合
9、获取将创立的汇合的长度作为while循环的条件(长度大于0),将汇合中的元素提取进去
10、在clientServer()办法中指定一个门路作为存储图片的中央,应用FileOutputStream类new进去的对象fileOutputStream来关上这个文件,
11、通过fileOutputStream.write办法将图片信息写入到对应的地址当中,实现图片的下载