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 "\n========================= \n "
                + " 姓名=" + name 
                + "\n 访问量=" + fangwen 
                + "\n 积分=" + jifen 
                + "\n 等级=" + dengji 
                + "\n 排名=" + paiming
                + "\n 原创=" + yuanchuang 
                + "\n 转载=" + zhuanzai
                + "\n 译文=" + yiwen 
                + "\n 评论=" + pinglun 
                + "\n 链接="+ link 
                + "\n 照片=" + photo 
                + "\n==========================\n";
    }
/*******省略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的单独的知识点,后面再总结补充。

 

posted @ 2016-08-31 20:01  HigginCui  阅读(1241)  评论(0编辑  收藏  举报