版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_25034451/article/details/79513095
java网页数据爬取
写在前面
在浏览器书签中有许多经典的东西,有时候什么忘记了需要去查询的,也非常方便,但是痛苦的事情是某一天打开书签,居然那个页面不知道飞哪去了,打不开,作为一个程序员,当然不能容忍这种事情发生,那就把它们都爬下来。
书签全部导出
以chrome浏览器为例:打开右上角三个点,设置项,找到书签,选择书签管理器,打开后点击整理下拉列表,有将书签导出到html文件选项,导出即可。
爬取前的处理
首先我们的书签可能有几种分类,为了处理方便,可以手动删除我们不需要的,也可以程序处理一下;以下处理是为了爬取方便,而不是删除不想要的。
先来看看导出的html文件的结构:
<!DOCTYPE NETSCAPE-Bookmark-file-1>
<!-- This is an automatically generated file.
It will be read and overwritten.
DO NOT EDIT! -->
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
<TITLE>Bookmarks</TITLE>
<H1>Bookmarks</H1>
<DL><p>
<DT><H3 ADD_DATE="1481295500" LAST_MODIFIED="1520685941" PERSONAL_TOOLBAR_FOLDER="true">书签栏</H3>
<DL><p>
<DT><A HREF="http://fanyi.baidu.com/?aldtype=16047#auto/zh" ADD_DATE="1481296188" ICON="data:image/png;base64,******">百度翻译</A>
<DT><A HREF="http://www.iciba.com/?=2016pcChromebookmark" ADD_DATE="1483001064" ICON="data:image/png;base64,******">爱词霸在线词典</A>
<DT><H3 ADD_DATE="1520685896" LAST_MODIFIED="1520694188">学习</H3>
<DL><p>
<DT><A HREF="https://www.csdn.net/" ADD_DATE="1520694161" ICON="data:image/png;base64,******">CSDN-专业IT技术社区</A>
<DT><A HREF="https://www.oschina.net/" ADD_DATE="1520694188" ICON="data:image/png;base64,******">开源中国 - 找到您想要的开源项目,分享和交流</A>
</DL><p>
</DL><p>
</DL><p>
在导出的数据中,base64,*,本来是一长串的字符,为了节省篇幅,我用*代替了。如上面导出的结果,有两种分类,一种是默认的(百度翻译和爱词霸在线词典),一种是在学习分类下(CSDN-专业IT技术社区和开源中国找到您想要的开源项目,分享和交流),一般想保存的肯定是学习下的,所以需要手动删除不需要的,我在这就不删除了,直接把上面所有的链接上的数据都拔下来。
InputStreamReader reader = null;
BufferedReader br = null;
StringBuffer stringBuffer =new StringBuffer("");
try {
br = new BufferedReader (new InputStreamReader (new FileInputStream (data), ENCODE));
String line = br.readLine();
while (line != null) {
if(line.trim().startsWith("<DT><A")){
stringBuffer.append(line.replaceAll("<DT>", ""));
}
line = br.readLine(); // 一次读入一行数据
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(reader!=null){
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(br!=null){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
好了,数据处理完毕,
处理结果如下
<A HREF="http://fanyi.baidu.com/?aldtype=16047#auto/zh" ADD_DATE="1481296188" ICON="data:image/png;base64,******">百度翻译</A> <A HREF="http://www.iciba.com/?=2016pcChromebookmark" ADD_DATE="1483001064" ICON="data:image/png;base64,******">爱词霸在线词典</A> <A HREF="https://www.csdn.net/" ADD_DATE="1520694161" ICON="data:image/png;base64,******">CSDN-专业IT技术社区</A> <A HREF="https://www.oschina.net/" ADD_DATE="1520694188" ICON="data:image/png;base64,******">开源中国 - 找到您想要的开源项目,分享和交流</A>
还是将多余字符用**代替
开始爬取并保存
private static void parser(StringBuffer stringBuffer) {
try{
Parser parser = new Parser(stringBuffer.toString());//构造解析对象
parser.setEncoding(ENCODE);//设置编码UTF-8
for (NodeIterator i = parser.elements (); i.hasMoreNodes(); ) {
final Node node = i.nextNode();
if(node.getText().contains("A HREF")){
if (node instanceof CompositeTag){
NetWork net = new NetWork();
/**获得链接并保存数据**/
net.getData(((CompositeTag)node).getAttribute("HREF"), new NetResult() {
@Override
public void onSuccess(String cache, String body,String data) {
//System.out.println(data);
String path = ((CompositeTag)node).getStringText();
path = path.replaceAll("[\\s\\\\/:\\*\\?\\\"<>\\|]","");//处理特殊字符
System.out.println("path:"+path);
if(path==null||path.isEmpty()){
path = "未命名";
}
FileUtil.stringToFile(data, "F:\\"+path+".html");//保存文件
}
@Override
public void onFailure() {
}
});
}
else
{
System.out.println(node.getText());
}
}
}
}
catch( Exception e ) {
System.out.println( "Exception:"+e );
}
}
数据保存完毕,再也不用担心数据丢失了(只是实现了一点功能,保存文字,并没有保存图片和js\css文件,以后有时间了继续)。