利用JAVA的BFS爬虫爬出豆瓣读书的评论和标签

直接上代码

目前还没写更改IP跳点的操作 ,爬到1400多条就被豆瓣服务器给BAN了,后续会慢慢地更新版本

TIP:BFS可无限爬取直至被BAN,DFS的话即使是换成尾递归也只能爬出400多条

TIPTIP:我正则表达式用的很烂,后面会把String操作全部转移到正则表达式中去,否则算法复杂度降不下来,大量异常的抛出可能也与String操作有关

package com;
/**
 * 孙煜晗爬虫魔改 version 1.3
 * sunYuhan
 */
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.regex.*;

public class exe {
    //提取的数据存放到该目录下
	//为html转化为的TXT文件
    private static String savepath="C:/Users/54781/Desktop/爬虫文件/";
    //等待爬取的url
    private static List<String> allwaiturl=new ArrayList<>();
    //记录爬取过的url
    private static Set<String> alloverurl=new HashSet<>();
    //记录所有url的深度进行爬取判断
    private static Map<String,Integer> allurldepth=new HashMap<>();
    //爬取的深度
    private static int maxdepth=10;
    
    public static void main(String args[]){
        //确定爬取的网页地址
        String strurl="https://book.douban.com";
        
        workurl(strurl,1);
        while(true)
        {
        	 String nexturl=allwaiturl.get(0);//获取list第一个元素
             allwaiturl.remove(0);//移除list第一个元素
             workurl(nexturl,allurldepth.get(nexturl)); //广搜  
        }
        
    }
    public static void workurl(String strurl,int depth){
        //判断当前url是否爬取过
        if(!(alloverurl.contains(strurl)||depth>maxdepth)){
        //建立url爬取核心对象
        try {
            URL url=new URL(strurl);
            //通过url建立与网页的连接
            URLConnection conn=url.openConnection();
            //通过链接取得网页返回的数据
            InputStream is=conn.getInputStream();
            
            System.out.println(conn.getContentEncoding());
            //一般按行读取网页数据,并进行内容分析
            //因此用BufferedReader和InputStreamReader把字节流转化为字符流的缓冲流
            //进行转换时,需要处理编码格式问题
            BufferedReader br=new BufferedReader(new InputStreamReader(is,"UTF-8"));
        
            //按行读取并打印
            String line=null;
           // String line2=null;
            //正则表达式的匹配规则提取该网页的链接
            Pattern p2=Pattern.compile("(?<=<span class=\"short\">).*?(?=</span>)");//找到评论
            Pattern p=Pattern.compile("<a .*href=.+</a>");//找到url
            Pattern p3=Pattern.compile("(?<=<a class=\"  tag\").*?(?=</a>)");//找到标签
            Pattern p4=Pattern.compile("(?<=<span property=\"v:itemreviewed\">).*?(?=</span>)");//找到书名
           // while()
            //建立一个输出流,用于保存文件,文件名为执行时间,以防重复
           // PrintWriter pw=new PrintWriter(new File(savepath+System.currentTimeMillis()+".txt"));

        	PrintWriter writer2 = null;//用于写评论
        	PrintWriter writer3=null;//用于写标签
            boolean flag=false;
            String word=null;
            String tag=null;
            while((line=br.readLine())!=null){
                //System.out.println(line);
                //编写正则,匹配超链接地址
               // pw.println(line);
                Matcher m=p.matcher(line);//url
                Matcher m2=p2.matcher(line);//评论
                Matcher m3=p3.matcher(line);//标签
                Matcher m4=p4.matcher(line);//书名
                String bookname;
                if(m4.find()&&!flag)//找到书名即可开始找标签和评论
                {
                	bookname=m4.group();
                	writer2=new PrintWriter(new File(savepath+"豆瓣评论/"+bookname+".txt"));
                	writer3=new PrintWriter(new File(savepath+"豆瓣标签/"+bookname+".txt"));
                	flag=true;
                }
                while(m3.find()&&flag)//爬标签
                {
                	tag=m3.group();
                	tag=tag.substring(tag.indexOf(">")+1, tag.length());//对tag的string处理
                	writer3.println(tag);
                	writer3.flush();
                }
                while(m2.find()&&flag)//爬评论
                {
                	word=m2.group();
                	writer2.println(word);
                	writer2.flush();
                }
                while(m.find()){//爬url
                    String href=m.group();
                    //找到超链接地址并截取字符串
                    //有无引号
                    href=href.substring(href.indexOf("href="));
                    if(href.charAt(5)=='\"'){
                        href=href.substring(6);
                    }else{
                        href=href.substring(5);
                    }
                    //除去HTTP协议那部分
                try{
                    href=href.substring(0,href.indexOf("\""));
                }catch(Exception e){
                    try{
                        href=href.substring(0,href.indexOf(" "));
                    }catch(Exception e1){
                        href=href.substring(0,href.indexOf(">"));
                    }
                }
                if(href.charAt(0)=='.'&&strurl.endsWith("/"))//判断简写URL问题
                	href=strurl+href.substring(2,href.length()-1);
                else if(href.charAt(0)=='.')
                	href=strurl+href.substring(1,href.length()-1);
                if(href.startsWith("https://book.douban.com/subject/")){
                    //保证在站内访问
                    //将url地址放到队列中
                    allwaiturl.add(href);
                    allurldepth.put(href,depth+1);
                        }
                
                    }
                
                }

        	//writer2.flush();
        	writer2.close();
           // pw.close();
            br.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //将当前url归列到alloverurl中
        alloverurl.add(strurl);
        System.out.println(strurl+"网页爬取完成,已爬取数量:"+alloverurl.size()+",剩余爬取数量:"+allwaiturl.size());
        }
        //用递归的方法继续爬取其他链接
       // String nexturl=allwaiturl.get(0);
       // allwaiturl.remove(0);
       // workurl(nexturl,allurldepth.get(nexturl));                
        }
}

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值