• 02_使用WebMagic爬虫获取CSDN推荐专家的个人博客信息


    本来是想抓取博客园的博客推荐的页面的,但由于一些博客进去的页面格式都不太相同,一时不想花时间去寻找规律,发现CSDN上面的格式较为单一,就决定以CSDN推荐专家的个人博客信息作为爬虫抓取的目标。

    【首先,查看一下CSDN的推荐专家的页面】

    【然后再查看一下主页面】

    准备用爬虫获取一下几个变量

    1.姓名

    2.访问量

    3.积分

    4.等级

    5.排名

    6.原创

    7.转载

    8.译文

    9.评论

    10.链接

    11.照片

    【工程截图】因为主要用到WebMagic,所有的jar包在WebMagic的git地址,自行下载。

    【User.java】便于展示,或者后期存入数据库用

    package com.cnblogs.test;
    
    public class User {
        private String name;  //名字
        private String fangwen; //访问数量
        private String jifen;  //积分
        private String dengji; //等级
        private String paiming; //排名
        private String yuanchuang;//原创
        private String zhuanzai;  //转载
        private String yiwen;    //译文
        private String pinglun;   //评论
        private String link;  //链接
        private String photo;  //照片  
        
        @Override
        public String toString() {
            return "
    ========================= 
     "
                    + " 姓名=" + name 
                    + "
     访问量=" + fangwen 
                    + "
     积分=" + jifen 
                    + "
     等级=" + dengji 
                    + "
     排名=" + paiming
                    + "
     原创=" + yuanchuang 
                    + "
     转载=" + zhuanzai
                    + "
     译文=" + yiwen 
                    + "
     评论=" + pinglun 
                    + "
     链接="+ link 
                    + "
     照片=" + photo 
                    + "
    ==========================
    ";
        }
    /*******省略get/Set方法******/ }

    【CSDNSpider.java】

    package com.cnblogs.test;
    
    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import us.codecraft.webmagic.Page;
    import us.codecraft.webmagic.Site;
    import us.codecraft.webmagic.Spider;
    import us.codecraft.webmagic.processor.PageProcessor;
    
    public class CSDNSpider implements PageProcessor{
        private static String keyword="java";
        private static int num;
        
        //专区网站的相关配置,包括编码、抓取间隔、重试次数等
        private Site site=Site.me().setRetryTimes(10).setSleepTime(1000);
        
        @Override
        public Site getSite() {
            return this.site;
        }
    
        @Override  
        public void process(Page page) {
            //如果url匹配"http://blog.csdn.net/experts.html"
            if(page.getUrl().regex("http://blog\.csdn\.net/experts\.html").match()){
                //获取div[@class='experts_list_wrap clearfix']内含有的全部链接
                List<String> listLink=page.getHtml().xpath("//div[@class='experts_list_wrap clearfix']").links().all();
                //因为在首页每个博主都有重复的链接,这里加一个去重的方法,这个方法很好用
                HashSet<String> hs=new HashSet<String>(listLink); //通过HashSet剔除重复的链接
                listLink.clear();
                listLink.addAll(hs); //将去重的的链接结合补充回listStr
                //将博主的主页的url加入到待抓取的队列中
                page.addTargetRequests(listLink);
            }else{  //此时进入了用户详细页面
                User user=new User();
                //首先获取姓名
                String name=page.getHtml().xpath("//div[@id='blog_userface']/span/a[@class='user_name']/text()").get();
                //这里获取
                String str=page.getHtml().xpath("//ul[@id='blog_rank']").get()+page.getHtml().xpath("//ul[@id='blog_statistics']").get();
                //部分变量以 "<sapn>XXXX<sapm>"的格式存在,我们可以使用正则表达式将整个"<sapn>XXXX<sapm>"获取匹配的字符串
                String regex="<span>(.*)+</span>";
                Pattern p1=Pattern.compile(regex);
                Matcher m=p1.matcher(str);
                //用来保存"<sapn>XXXX<sapm>"中间的XXXX的集合
                List<String> strList=new ArrayList<>();  
                while(m.find()){
                    //这里的m.group()的格式为: "<span>403581次</span>" 或  "<span>7526</span>" 或 "<span>第1885名</span>" 的格式
                    String s=m.group().split("<span>|</span>")[1]; //切割之后为 s[0]="<span>" s[1]="404581次" s[2]="<span>",所以我们取s[1]
                    strList.add(s); //将s[1]添加至集合中
                }
                String fangwen=strList.get(0);  //访问
                String jifen=strList.get(1);    //积分
                String paiming=strList.get(2);  //排名
                String yuanchuang=strList.get(3); //原创
                String zhuanzai=strList.get(4);   //转载
                String yiwen=strList.get(5);     //译文
                String pinglun=strList.get(6);   //评论
                
                
                //等级存放在<img src=http://c.csdnimg.cn/jifen/images/xunzhang/jianzhang/blog6.png>中
                //1级对应:blog1.png, 6级对应:blog6.png
                String dengji=page.getHtml().xpath("//img[@id='leveImg']/@src").get();
                dengji=dengji.substring(dengji.length()-5, dengji.length()-4);  //获取倒数第5个字符
                
                //获取当前页的url
                String photo=page.getHtml().xpath("//div[@id='blog_userface']/a/img/@src").get();
                
                String link=page.getUrl().toString();
                
                //将所有的数据保存如User对象中
                user.setName(name);
                user.setFangwen(fangwen);
                user.setJifen(jifen);
                user.setDengji(dengji);
                user.setPaiming(paiming);
                user.setYuanchuang(yuanchuang);
                user.setZhuanzai(zhuanzai);
                user.setYiwen(yiwen);
                user.setPinglun(pinglun);
                user.setLink(link);
                user.setPhoto(photo);
                System.out.println(user.toString());
                
            }
            
        }
        
        public static void main(String[] args) {
            //url入口
            Spider.create(new CSDNSpider())
            .addUrl("http://blog.csdn.net/experts.html")
            .thread(5)
            .run();
        }
    
    }

    【运行结果】

    【注意点】

    这两块信息分布在两个ul上,所以就出现了程序里

    整合两个ul的情况。

     

     另外,注意下这几个处理方式不同

     【总结】

    知识点一:List<String>去重的方法:

    知识点二:正则表达式从一个长字符串中获取符合要求的字符串数组(多个满足条件,就组成数组喽)

    知识点三:截取某一段字符串的后面几位(之前有点忘记了,现在记下)

    总之WebMagic还是挺好上手的,当然正则表达式巧妙的利用会事半功倍。

    另外就是WebMagic的单独的知识点,后面再总结补充。

  • 相关阅读:
    线索二叉树
    正则表达式之后向引用
    进步的阶梯
    树和二叉树
    java 执行 exe 文件
    Electron + Vue如何实现不同窗口之间的通信(项目总结 第一个)
    liunx 修改 ip 地址
    桌面快捷工具
    微信小程序长列表组件 recycle-view 修改,使其可以下拉刷新
    微信小程序 textarea 文本滚动不了的bug
  • 原文地址:https://www.cnblogs.com/HigginCui/p/5827356.html
Copyright © 2020-2023  润新知