java爬虫案例--webmagic

用webmagic写了一个爬虫
爬虫地址:https://job.oschina.net/search?type=%E8%81%8C%E4%BD%8D%E6%90%9C%E7%B4%A2&key=&exp=0&edu=0&nat=1&city=%E5%85%A8%E5%9B%BD&p=1

爬虫所有的招聘职位信息(文末附代码下载及使用说明)

一、查询总的页数
service层代码:

//获取总条数
        String spiderUrl = MessageFormat.format(URL, 1);
        Spider.create(new TotalPositionPageProcessor()).addUrl(spiderUrl).thread(1).run();
        logger.info("总数据量:"+totalPosition+"   总页数:"+totalPage);

其中URL值为:https://job.oschina.net/search?type=%E8%81%8C%E4%BD%8D%E6%90%9C%E7%B4%A2&key=&exp=0&edu=0&nat=1&city=%E5%85%A8%E5%9B%BD&p={0}

创建pageProcess代码:

public class TotalPositionPageProcessor implements PageProcessor{

     //抓取网站的相关配置,包括编码、抓取间隔、重试次数等
    private Site site = Site.me().setRetryTimes(3).setSleepTime(100);

    // process是定制爬虫逻辑的核心接口,在这里编写抽取逻辑
    @Override
    public void process(Page page) {
         // 匹配出总条数
        String count = page.getHtml().xpath("//div[@class='layout-column article']/div/div/div[@class='layout-column']/div/text()").regex("([0-9]+)").toString();
        logger.info("总数据量为:"+count);
        SpiderOschinaServiceImpl.totalPosition = count;
        //匹配出总页数
        List<String> pageCount = page.getHtml().xpath("//div[@class='pagination text-center']/ul/li/a/text()").all();
        logger.info("总页数为:"+pageCount.get(pageCount.size()-2));
        SpiderOschinaServiceImpl.totalPage = pageCount.get(pageCount.size()-2);
    }

    @Override
    public Site getSite() {
        return site;
    }

}

在第一页上有多少个职位多少页数据(https://job.oschina.net/search?type=%E8%81%8C%E4%BD%8D%E6%90%9C%E7%B4%A2&key=&exp=0&edu=0&nat=1&city=%E5%85%A8%E5%9B%BD&p=1
总页数网页源代码:
这里写图片描述
通过xpath获取到一共多少职位数据:933

 String count = page.getHtml().xpath("//div[@class='layout-column article']/div/div/div[@class='layout-column']/div/text()").regex("([0-9]+)").toString();

这里写图片描述
通过xpath获取到一共多少页:94

        List<String> pageCount = page.getHtml().xpath("//div[@class='pagination text-center']/ul/li/a/text()").all();
        logger.info("总页数为:"+pageCount.get(pageCount.size()-2));
        SpiderOschinaServiceImpl.totalPage = pageCount.get(pageCount.size()-2);

二、获取每个职位详情
获取每个职位的详情,比如职位、薪资、公司、技能要求
爬取职位详情页:如:https://job.oschina.net/position/11027_2807239_27862

从上面可以获取到一共多少页,所有可以获取到列表页所有的请求地址:

public static List<String> rulList = null;//每一页的请求


if(totalPage!=null && !"".equals(totalPage) && Integer.parseInt(totalPage)>0){
            int totalPages = Integer.parseInt(totalPage);
            rulList = new ArrayList<String>();
            for (int i = 0; i < totalPages; i++) {
                    System.out.println(MessageFormat.format(URL,i + 1));
                    rulList.add(MessageFormat.format(URL,i + 1));
             }
        }

实现pageProcess抓取页面:

//每一个连接都会进入processor方法中进行抽取
public class PositionDetailPageProcessor implements PageProcessor{

     //抓取网站的相关配置,包括编码、抓取间隔、重试次数等
    private Site site = Site.me().setRetryTimes(3).setSleepTime(100);

    //列表页https://job.oschina.net/search?type=%E8%81%8C%E4%BD%8D%E6%90%9C%E7%B4%A2&key=&exp=0&edu=0&nat=1&city=%E5%85%A8%E5%9B%BD&p=1
    public static final String URL_LIST = "https://job\\.oschina\\.net/search\\?type=%E8%81%8C%E4%BD%8D%E6%90%9C%E7%B4%A2&key=&exp=0&edu=0&nat=1&city=%E5%85%A8%E5%9B%BD&p=\\d+";

    //详情页https://job.oschina.net/position/11317_2828767_27953
    public static final String URL_POST = "https://job\\.oschina\\.net/position/\\w+";

    //有一个url这个方法和pipeline里的process方法都会再执行一遍
    @Override
    public void process(Page page) {
        //列表页
        if(page.getUrl().regex(URL_LIST).match()){
            System.out.println("将第几页连接放入待抓取队列中");
            page.addTargetRequests(page.getHtml().xpath("//div[@class='layout-left title']/a/@href").all());//获取详情页地址进行结果抽取
            page.addTargetRequests(SpiderOschinaServiceImpl.rulList);//获取所有页面的连接并进行抽取
        }else{//详情页
            System.out.println("抽取详情页数据");
            page.putField("name", page.getHtml().xpath("//div[@class='col-xs-9']/h1/@title"));//职位
            page.putField("salary", page.getHtml().xpath("//div[@class='col-xs-9']/div/b/text()"));//薪资
            String require = page.getHtml().xpath("//span[@id='ex-position-skills']/a/text()").all().toString().replace(",", "/");
            page.putField("require", require.substring(1, require.length()-1));//要求
            page.putField("company", page.getHtml().xpath("//h3[@class='text-left']/strong/a/text()"));//公司
        }
    }   

    @Override
    public Site getSite() {
        return site;
    }

}

page.addTargetRequests方法将链接加入队列中等待下载爬取数据。
每个链接都会实现PageProcessor的process方法和Pipeline的process方法(如果实现了该接口)

三、处理结果
结果处理实现Pipeline接口

public class PositionDetailPipeline implements Pipeline{

    @Override
    public void process(ResultItems resultItems, Task task) {
        System.out.println("输出结果:");
        //遍历所有结果,输出到控制台,上面例子中的"name"、"require"、"salary"、"company"都是一个key,其结果则是对应的value
        for (Map.Entry<String, Object> entry : resultItems.getAll().entrySet()) {
            System.out.println(entry.getKey() + "  -------------------->  " + entry.getValue());
        }

    }

}

打印处理的结果:

输出结果:
name  -------------------->  前端开发工程师 (Web方向) (接受实习生和兼职顾问)
salary  -------------------->   4K-8K 
require  -------------------->  html5/ mysql/ php/ html+css+jq/ PS
company  -------------------->  嘉兴想天信息科技有限公司

四、代码下载
代码下载地址:http://download.csdn.net/detail/u012385190/9696972

本项目使用maven环境搭建,运行是用quartz定时器启动项目的。如果不熟悉quartz,也可以直接在类SpiderOschinaServiceImpl运行main方法即可。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值