给个需要:通过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办法将图片信息写入到对应的地址当中,实现图片的下载
发表回复