1背景
经常上贴图的论坛(Discuz!),每次打开帖子的时候,由于帖子的图片太多,每次都要等不少时间才能看到所有的图片,比较麻烦;同时经常会打开看过的帖子。为了解决这个问题,写了个小爬虫,定期把最新的帖子中的图片下载到本地。
2目标
自动登录、智能发现为抓取的帖子、智能提取图片URL、多线程下载到本地。
3整体流程图
4,使用到的工具和软件
VisualSVN Server:Windows下的SVN服务,使用非常简单和傻瓜,windows下个人开发强力推荐。更多可参考:
Paros:web安全漏洞扫描工具。可拦截所有的HTTP的请求和相应。这里用来分析登录时提交的数据。
Firebug, mvn:这个不多说了,谁用谁知道。
5,使用到的框架
http client 4.1。 用来发起Http get和post请求。本来用的是3.1版本,结果多线程下载的时候,底层出现了线程死锁问题。看到官网也强力推荐升级,然后升级解决了这个问题。
6,关键代码和步骤
COOKIE的手动处理
httpclient没有自动把登录的COOKIE信息放到请求的消息头里,需要手工处理。
HttpGet httpget = new HttpGet(url);
if (isNeedLogin) {
httpget.setHeader("COOKIE", getCOOKIEString());
}
public static String getCOOKIEString() {
StringBuffer stringBuffer = new StringBuffer();
for (COOKIE item : logonCOOKIEs) {
stringBuffer.append(item.toString());
stringBuffer.append(";");
}
if (stringBuffer.length() > 1) {
return stringBuffer.substring(0, stringBuffer.length() - 1)
.toString();
}
return stringBuffer.toString();
}
Http client多线程设置:
ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager();
cm.setMaxTotal(50);
// 多线程的
httpClient = new DefaultHttpClient(cm);
图片下载代码:
/**
* 下载图片到本地
*
* @return 是否发生网络异常
*/
public static boolean downloadPic(String url, String path) {
// GetMethod get = new GetMethod(url);
HttpGet httpget = new HttpGet(url);
try {
HttpResponse resp = httpClient.execute(httpget);
File storeFile = new File(path);
// 得到网络资源的字节数组,并写入文件
FileOutputStream out = new FileOutputStream(storeFile);
InputStream in = resp.getEntity().getContent();
byte[] buffer = new byte[1024];
int count = -1;
while ((count = in.read(buffer)) != -1) {
out.write(buffer, 0, count);
}
out.flush();
out.close();
} catch (Exception e) {
log.error("线程" + Thread.currentThread().getName()
+ "号. 下载图片异常. URL为" + url, e);
return false;
}
return true;
}
mvn创建java工程的命令:
mvn archetype:create -DgroupId=com.mike -DartifactId=picgetter -DpackageName=org.mike
7,展望
BT视频的自动下载,最近迅雷开放了API,通过JNI的方式调用迅雷,就可以实现视频的自动下载,不过现在暂时没有这个需求。