WebCrawler Java小爬爬 从入门到放弃 第七章

整理一下思路,准备结束我们的小爬爬之路。
本来想用PowerDesigner画几张图 结果惨不忍睹 : )
所以就文字简述一下吧

我们要爬的这个网页有四级页面:
1级页面:目录列表
2级页面:书籍介绍页面
3级页面:书籍章节页面
4级页面:书籍信息
所以我们采用深度优先算法的思想,伪代码如下:

从传入的初始页面,将1级页面压入栈S1
while(S1!=null){
取S1栈顶页面x;
S1弹栈;
从x里正则获取2级页面;
将2级页面压入栈S2;
while(S2!=null){
取S1栈顶页面y;
S1弹栈;
从y里正则获取三级页面z 同时获取作者、书名等信息;
将三级页面从入队列Q(先进先出,写入本地时 不会产生倒序)
while(Q!=null){
取队头页面m;
Q出队;
从m里获取书籍文字内容;
}
}
}

在实际获取书籍信息的同时,我们也在访问数据库,跟新数据库的信息,并且在本地建立相应的文件目录结构。

本来想自己写栈和队列的,但Java里封装了Stack Queue两个类,很好用,也就作罢。

下面是处理URL的类,其中包含了深度优先算法:

import java.io.BufferedReader;  
import java.io.IOException;
import java.io.InputStreamReader;  
import java.net.URL;  
import java.net.URLConnection;  
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
import java.util.regex.Matcher;  
import java.util.regex.Pattern;  
/**
 *   
 * @author Mr.Dragon
 * 
 *
 */
public class URLContent {  
    public static String getURLContent(String url,String charset) {  
        String urlContent = "";   
        BufferedReader in = null;  
        try {  
            URL realURL = new URL(url);  
            URLConnection connection = realURL.openConnection();  
            connection.connect();   
            in = new BufferedReader(new InputStreamReader(  
                    connection.getInputStream(), charset),50000);  
            String line;  
            while(null != (line = in.readLine())) {  
                urlContent += line;  
            }  
        } catch (Exception e) {  
            O.p("Get URLContent failed!" + e);  
            e.printStackTrace();  
        }  
        return urlContent;  
    }


    public static void processingAndWrite(String urlcontent) 
            throws IOException{ 
        String author = null;
        String bookname = null;
        Pattern p = null;
        Matcher m = null;
        String href = null;
        String content = getURLContent(urlcontent,"GBK");
        int last = 0;
        {
            /**
             * get count of catalog 
             *  
             */
            p = Pattern.compile("<em .+?pagestats.+?/(.+?)</em>");
            m = p.matcher(content);
            m.find();
            last = Integer.parseInt(m.group(1));
        }
        {
            /**
             * search the URL of catalog
             */
            p = Pattern.compile("class=\"first.+?href=\"(.+?)\\d+.html\"");
            m = p.matcher(content);
            m.find();
            href = m.group(1);
        }
        //DFS(Depth-First-Search)           
        String url;
        Stack<String> s1 = new Stack<String>();
        Stack<String> s2 = new Stack<String>();
        Queue<String> q = new LinkedList<String>();
        for(int i = 1;i < last; i++){
            url = href+i+".html";
            s1.push(url);
        } 
        while (!s1.empty()){
            O.p("1st level catalog :"+s1.peek());  
            content = getURLContent(s1.pop(),"GBK");
            p = Pattern.compile("class.+?l_pic.+?href=\"(.+?)\"");
            m = p.matcher(content);
            while(m.find())s2.push(m.group(1));
            String last_url_start ;
            while(!s2.empty()){
                O.p("2nd level catalog :"+s2.peek()); 
                last_url_start = s2.peek().substring
                        (0,s2.peek().lastIndexOf('/'));
                content = getURLContent(s2.pop(),"GBK");
                p = Pattern.compile("<dd><a href=\"(.+?)\" title=.+?</dd>");
                m = p.matcher(content);             
                while(m.find()){  
                    String last_url_end = m.group(1).substring
                            (m.group(1).lastIndexOf('/'));
                    q.offer(last_url_start + last_url_end);
                }
                p = Pattern.compile("<h1>(.+?)</h1>.+?");
                m = p.matcher(content);
                m.find();
                bookname = m.group(1);
                p = Pattern.compile("<meta name=\"author\" content=\"(.+?)\"");
                m = p.matcher(content);
                m.find();
                author = m.group(1);
                O.p("Book name:"+bookname+" Author:"+author); 
                while(null != q.peek()){
                    O.p("3rd level catalog :"+q.peek());
                    content = getURLContent(q.peek(),"GBK");
                    q.poll();
                    p = Pattern.compile("<title> (.+?)</title>");
                    m = p.matcher(content);                         
                    m.find();  
                    O.p(m.group(1));
                    String bookcontent = replaceHTMLMarks(m.group(1));
                    BookWriter.writeIntoFile(bookname, author,bookcontent );
                }
            }
        }       
    }

    public static String replaceHTMLMarks(String content){ 
        content = content.replaceAll("<p .*?>", "\r\n"); 
        content = content.replaceAll("<br\\s*/?>", "\r\n"); 
        content = content.replaceAll("\\<.*?>", "");  
        return content;
    }
    public static String getCharSet(String content){
        Pattern p = Pattern.compile("script charset=\"(.+?)\"");
        Matcher m = p.matcher(content);
        m.find();
        return m.group(1);
    }
}  

getCharSet()这个方法在设计时考虑到了,因为有的网页字符集是UTF-8,有的是GBK。…..但最后没有用到这个方法。

replaceHTMLMarks()在html中有很多标记,我们写入本地时要用对应的字符替换掉,意图显示正常。

程序最终运行结果图:
这里写图片描述

Ps:
没有开玩笑(严肃脸),我们最后放弃了,因为从四级页面获取文章详细信息的时候,正则表达式没有问题,但是读入的流里,就没有文章那一段。先开始博主以为是加密,但是这种网站也加密?舍友说可能是内嵌的PDF,Java的流读不进来。博主以为有可能,所以借了几本书JS的书,准备十一看。毕业设计如果也做大数据的话,这个爬虫会再加入并行计算和分布式吧,写成servlet,再租个服务器,或者免费的阿里云?

关于全部的源代码,可在评论里留下你的邮箱。
如有疑问、建议或指导,欢迎在评论区留言,或写邮件到我的邮箱:
keepslientiPhone@iCloud.com

后记(编辑于2016-10-19):

因为大数据的这个课程设计,组长要求必须是爬出来的,不能手动下载。
然后啊。。。。。。。。。。苦思冥想
最后发现这个文章是JS动态加载的 然后去了解了下AJAX
这里写图片描述
用FireBug看了下网页网络状态
这里写图片描述
最后用模拟了这段代码 最终成功爬到了文章 哈哈 后面的词频分析 聚类 拟合就主要交给他们了 终于可以轻松一下了 -。-
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值