JAVA网络爬虫
https://tieba.baidu.com/p/2256306796?red_tag=1781367364
上边连接为百度壁纸贴吧,编写程序从网上能把所有壁纸爬到本地。
图片元素的源代码例子为:
<img class="BDE_Image" src="https://imgsa.baidu.com/forum/w%3D580/sign=43e292947c1ed21b79c92eed9d6fddae/6bfab2fb43166d228b3c16f2472309f79052d20a.jpg" width="560" height="314" pic_type="0">
思路:
1.使用url这个类建立网络连接并发送请求。
2.读取链接的html网页
3.从读取的网页中查找img元素
4.从查找到的img元素中提取http地址
5.从提取到的地址下载图片
为了能够高效的下载图片,可以使用多线程的方式,每找到一个图片地址就让一个线程取处理它。
首先,写一个任务类,给定网络地址和本地地址,能够从网络下载图片到本地
public class task implements Runnable {
String s1;//网络地址
String s2;//图片编号
public task(String s1, String s2) {
this.s1 = s1;
this.s2 = s2;
}
@Override
public void run() {
try {
HttpURLConnection connection = (HttpURLConnection)
new URL(s1).openConnection();//建立连接
InputStream in = connection.getInputStream();
FileOutputStream image = new FileOutputStream("图片/"+s2+".gif");//根本图片编号生成本地地址
byte[] buf = new byte[1024*8];
while(true) {//读取图片字节
int len = in.read(buf);
if(len == -1) {
break;
}
image.write(buf, 0, len);//存储到本地
}
image.close();
System.out.println("已爬到"+s2+"张图");
Thread thread =Thread.currentThread();
thread.stop();
}catch (IOException e) {
e.printStackTrace();
}
}
}
下来写程序能够从读取网络Html代码并且能够找到所有图片地址,并调用该任务类下载图片。
public class copyPicture {
public static void main (String[] args) throws IOException {
ExecutorService service = new ThreadPoolExecutor(10, 10, 0, TimeUnit.SECONDS,
new LinkedBlockingQueue<>());
//https://tieba.baidu.com/p/2256306796?red_tag=1781367364
//<img class="BDE_Image" src="https://imgsa.baidu.com/forum/w%3D580/sign=43e292947c1ed21b79c92eed9d6fddae/6bfab2fb43166d228b3c16f2472309f79052d20a.jpg" width="560" height="314" pic_type="0">
HttpURLConnection connection = (HttpURLConnection)
new URL("https://tieba.baidu.com/p/2256306796?red_tag=1781367364").openConnection();
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
int i=1;
String l;
StringBuffer s=new StringBuffer("");
while((l=reader.readLine())!=null) {
s.append(new String(l));
}
// System.out.println(s);
File file=new File("图片");
file.mkdir();
int current=0;
while((current=s.indexOf("<img class=\"BDE_Image\"",current))!=-1){
int end=s.indexOf(">",current);
current++;
String s1=s.substring(current,end);
int current1=s1.indexOf("https:");
int ends1=-1;
String s2="";
if(current1!=-1){
ends1=s1.indexOf("\"",current1);
s2=s1.substring(current1,ends1);
service.submit(new task(s2, String.valueOf(i++)));
}
}
service.shutdown();
}
}
上边例子中,在查找图片元素时,截取了两次字符串,第一次使用indexOf()找到img标签,并将标签截取下来,第二次找到img标签中的http地址。最后将地址交给线程去处理。
其实还可以采用正则表达式来匹配img标签中的Http地址
static final Pattern PATTERN = Pattern.compile("<img class=\"BDE_Image\" src=\"(.*?)\">");
while (matcher.find()) {
// 获取图片的路径
String imageURL = matcher.group(1);
service.submitnew task(imageURL, String.valueOf(i++))
}