抓取一个网站特定的全部图片(JAVA)

1. 目的

     用五笔时,如果碰到不会拆的字,只好换回拼音。但这样做治标不治本,于是到网上找五笔反查工具。最后发现一个不错的网站——不仅有每个字对应的五笔码,还有其字根图。可惜的是,这是一个网站。换句说,就是每次查的时候都要上网。很自然的,会想到将这个网站上的五笔码以及对应的字根图保存到本地上,再写个查询程序做成本地版的>_<

 

2. 准备工作——网页特点分析

                      

      网站(http://www.wb86.com/wbcx)提供了两种查询方式:一种是输入要查询的字;另外一种是一页接着一页地查看。由于懒得找字库,就选择了第二种方式。在此方式下,第一页的URL是http://www.wb86.com/wbcx/index5.asp?page=1,第二页的URL是http://www.wb86.com/wbcx/index5.asp?page=2,第三页的URL是http://www.wb86.com/wbcx/index5.asp?page=3。通过前三个页的URL,有理由相信第X页的URL是http://www.wb86.com/wbcx/index5.asp?page=X
      解决URL问题后,就要分析如何从单个网页得到所需要的资源。查看第一页的源代码发现“86五笔编码”只出现过一次,而且其后面就是想要的五笔码。因此得到服务器发回的内容后,再定位到“86五笔编码”就能得到相应的五笔码。字根图的URL地址出现在五笔码之后,而且都是以“http://www.wb86.com/GIF-82”开头的。因此在“86五笔编码”之后的内容中,找到第一个以“http://www.wb86.com/GIF-82”开头的URL,就是需要的图片地址了。

 

3. 算法流程

for( 第一页到最后一页 ) {
 获取这一页的源代码
 从源代码中提取五笔码,字根图的URL
 获取字根图
}

 

4. 源代码

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.LinkedList;

import javax.imageio.ImageIO;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;


public class Clawler {
private static final int END_PAGE = 6764;
private static final String PREFIX = "http://www.wb86.com/wbcx/index5.asp?page=";
private static final String CODE_SAVE_PATH = "D:\\Wubi\\WubiCode.txt";
private static final String IMG_SAVE_PATH_PREFIX = "D:\\Wubi\\img\\";

private static LinkedList queue = new LinkedList();

private static String m_imguri;

public static void main(String[] args) throws IOException {
HttpClient httpClient = new DefaultHttpClient();

FileWriter fw = null;
fw = new FileWriter(CODE_SAVE_PATH);

for(int i = 1; i <= END_PAGE; ++i) {
HttpUriRequest request = new HttpGet(PREFIX + i);

try {
HttpResponse response = httpClient.execute(request);

HttpEntity entity = response.getEntity();
StringBuilder builder = new StringBuilder();
if( entity != null ) {
InputStream is = entity.getContent();
byte[] tmp = new byte[2048];
while( is.read(tmp) != -1 ) {
builder.append(new String(tmp));
}

fw.write( getWubiCode(builder.toString(), i) );
downloadImg(m_imguri, IMG_SAVE_PATH_PREFIX + i + ".gif", i);
}

}
catch( Exception e ) {
queue.addLast((Integer)i);
e.printStackTrace();
}

if( i%100==0 ) {
fw.flush();
}
}

System.out.println("\n missing Code");
while( !queue.isEmpty() ) { //下载失败的页面
System.out.println(queue.element());
queue.removeFirst();
}

System.out.print("all done");
fw.close();
httpClient.getConnectionManager().shutdown();
}

public static String getWubiCode(String page, int number) { //提取五笔码,字根图的URL
StringBuilder save = new StringBuilder();
page = page.substring(page.indexOf("86五笔编码"));

int index = 7;
while( page.charAt(index)!= '<' ) save.append(page.charAt(index++));
save.append(System.getProperty("line.separator"));

index = 0;
StringBuilder imgpath = new StringBuilder();
page = page.substring(page.indexOf("http://www.wb86.com/GIF-82"));
while( page.charAt(index) != '\"' ) imgpath.append(page.charAt(index++));
m_imguri = imgpath.toString();

save.insert(0, imgpath.charAt(imgpath.length() - 5));
save.insert(1, ' ');

return save.toString();
}

public static void downloadImg(String url, String path, int number) { //下载图片
try {
File out = new File(path);
BufferedImage buffer = ImageIO.read(new URL(url));
if( buffer == null ) {
queue.addLast(number);
System.out.println(number + " " + url);
}
else {
ImageIO.write(buffer, "gif", out);
}
}
catch( IOException e ) {
queue.addLast(number);
System.out.println(url);
System.out.println(e.getMessage());
}
}
}

 

 

5. 参考资料
a. httpClient4.1入门教程(中文版)
http://wenku.baidu.com/view/0a027c5e804d2b160b4ec029.html
b. 论坛图片爬虫的一种实现
http://www.iteye.com/topic/1044289
c. 最简单的搜索引擎思路
http://www.iteye.com/topic/1055424

 

 

 

posted @ 2011-11-29 11:43  风中之炎  阅读(6668)  评论(1编辑  收藏  举报