黑马程序员技术交流社区
标题:
自己写的图片下载器
[打印本页]
作者:
赵兵锋
时间:
2012-6-11 01:58
标题:
自己写的图片下载器
自己折腾的图片下载器,会查找二层链接里的图片,类似于图片整站下载的简易版。
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
public class DownloadPic
{
private static final String startUrl = "http://www.baidu.com/";//起始地址
private static final String filePath= "E:/downPic";//文件存放路径
public static void main(String[] args)
{
start(startUrl,0);//开始搜索
}
static void start(String source,int count)//这里的count参数是为了以后程序功能扩展
{
ArrayList<String> list = new ArrayList<String>();//用来装链接地址
int t= count;
list.add(source);
try {
URL url = new URL(source);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
File file_dir = new File(filePath);//图片的存放目录
if(!file_dir.exists())
file_dir.mkdir();
file_dir = null;
FileOutputStream file = new FileOutputStream(new File(filePath+"/t"+t+".txt"));//起始地址读出的数据
String str;
while((str=in.readLine())!=null)
{
file.write(str.getBytes());
}
in.close();
file.close();
} catch (Exception e) {
e.printStackTrace();
}
String ps2 = "href=\"([^\"]+)\"";//指定获取网页代码里中引号内的内容即地址
Pattern p=Pattern.compile(ps2);
Matcher m;
String ss="";
BufferedImage img;
try {//将首页的代码取出
FileInputStream file = new FileInputStream(new File(filePath+"/t"+t+".txt"));
BufferedReader in = new BufferedReader(new InputStreamReader(file));
String str;
while((str=in.readLine())!=null)
{
ss=ss.concat(str);
}
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
m =p.matcher(ss);//开始解析首页中的地址
while(m.find())
{
String temp = m.group().substring(6,m.group().length()-1);//取出中的http://www.baidu.com
if(temp.endsWith(".css")||temp.endsWith(".js")||temp.endsWith(".jsp")||temp.equals("/"))
continue;//如果地址以css、js、jsp、/结尾就继续下一个地址的查找,因为这些类型的地址取不到图片
try {
new URL(temp);
System.out.println(temp);
if(list.contains((String)temp))//防止装入重复地址
continue;
list.add(temp);
} catch (MalformedURLException e) {//URL格式错误,因为有的地址用的是相对地址,如href="help.html"
int i = source.lastIndexOf("/");
try {
new URL(source.substring(0,i+1)+temp);//根据起始地址,找出父路径,再与相对路径拼接.如http://www.baidu.com/help.html
if(list.contains((String)source.substring(0,i+1)+temp))//能执行到这里说明上一句不报异常,即说明新地址格式正确
continue;
list.add(source.substring(0,i+1)+temp);//将新地址装进list中
System.out.println(source.substring(0,i+1)+temp);
} catch (MalformedURLException e1) {
continue;
}
}
}
for(int i =0;i<list.size();i++)//遍历list中的网页,找出其中的图片
{
fun(list.get(i),i);//i是此网页编号
}
}
static void fun(String source,int count)
{
ArrayList<String> list = new ArrayList<String>();
try {//将此网页源代码存储到文本
URL url = new URL(source);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
FileOutputStream file = new FileOutputStream(new File(filePath+"/t"+count+".txt"));
String str;
while((str=in.readLine())!=null)
{
file.write(str.getBytes());
}
in.close();
file.close();
} catch (Exception e) {
return;
}
String ps = "src=\"([^\"]+)\"|src=\'([^\']+)\'";//找到当前网页中所有src="..."或src='...'格式的字符串
Pattern p=Pattern.compile(ps);
Matcher m;
String ss="";
BufferedImage img;
try {
FileInputStream file = new FileInputStream(new File(filePath+"/t"+count+".txt"));//这个文件里存储着当前网页的源代码
BufferedReader in = new BufferedReader(new InputStreamReader(file));
String str;
while((str=in.readLine())!=null)
{
ss=ss.concat(str);
}
} catch (Exception e) {
return;
}
m =p.matcher(ss);
while(m.find())
{
String temp = m.group().substring(5,m.group().length()-1);//从src="http://www.baidu.com/banner.jpg"提取出引号内的地址
if(temp.endsWith(".gif"))//找到gif图片
{
if(list.contains(temp))//刚解析的图片地址早已经早list中存在,重复了,继续下一个地址
continue;
list.add(temp);
try {
img = ImageIO.read(new URL(temp));//将图片文件存储到本地
if(img!=null)
{System.out.println(temp);
File file = new File(filePath+"/"+temp.substring(temp.lastIndexOf("/")));//文件以图片在地址中的名字命名
ImageIO.write(img, "GIF",file);
}
} catch (MalformedURLException e) {//这一张图片存储失败,放弃,继续下一张
continue;
} catch (IOException e) {
continue;
}
}
else if(temp.endsWith(".jpg")||temp.endsWith(".jpeg"))//找到jpg\jpeg图片
{
if(list.contains(temp))
continue;
list.add(temp);
try {
img = ImageIO.read(new URL(temp));
if(img!=null)
{System.out.println(temp);
File file = new File(filePath+"/"+temp.substring(temp.lastIndexOf("/")));
ImageIO.write(img, "JPG",file);
}
} catch (MalformedURLException e) {
continue;
} catch (IOException e) {
continue;
}
}
}
}
}
//思路:用url.openStream()获得起始地址的输入流,进而将地址里的数据存储到本地文件里,接着用正则表达式在文件里寻找这类的href链接地址,同样取出其中数据并存储到本地文件
//接下来在本地存储的网页html代码里用正则表达式寻找src="http://www.baidu.com/banner.jpg"这类的src地址,将以图片类型结尾的地址里的数据取回,在本地存储为图片文件。
//作用:假如给定起始地址为http://www.baidu.com/,在该页面及该页面使用href链接到的页面中的jpg\jpeg\gif图片保存到本地。
//此程序只找了两层链接,通过将start方法扩展,可实现多层链接查找
复制代码
作者:
一生一世
时间:
2012-6-11 07:19
不错,兄弟写的代码不错,实现了二层连接里的图片下载,只是在代码的设计方面有点不太好,比如说通篇的代码只有两个static函数,应该把实现不同功能的代码封装到不同的方法中,以便于重用,比如说那个ArrayList 就可以定义为全局变量,这样就节省点内存。个人之见,仅供参考
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2