爬虫之黑龙江科技大学 URP大战-yellowcong

本文介绍了一个针对URP教务系统的成绩爬虫项目,包括使用HttpClient进行POST和GET请求、利用Jsoup解析HTML、获取成绩数据等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

爬虫的确是挺爽的,直接通过爬取服务器上的数据,然后可以做成APP或则自动发表到自己的网站上面去,我当时是想做URP学校APP的网站,当时想想,都毕业了,懒得做了,就做了一点关于成绩的爬取,希望各位看官拍砖。这个URP爬虫地址:http://git.oschina.net/yellowcong/urp

框架

1、爬虫的请求,是我 HttpClient的POST和GET请求和Session的保持-yellowcong 写到了Utils包
2、Html解析工具是使用的jsoup-1.7.3.jar ,这个玩意,真是神器啊,我以前用他来解析过推酷的数据,我使用爬虫,爬了一堆推酷的数据,项目地址给大家发一下http://git.oschina.net/yellowcong/tuicool

谈谈如何做爬虫

1、判断请求的方式是POST还是GET
2、解析HTML界面

这里写图片描述

通过浏览器,查看发送的参数
这里写图片描述

数据 解析,对于这个URP系统,是table布局,但是在Jsoup下,还不是小菜一碟,我还是想说jsoup真的是java解析的神奇

这里写图片描述

URP的案例

这种需要session保存的爬虫,需要做好session失效的操作,不过我这个小案例,里面没有做,啊哈哈哈

常量类 URP

package com.yellowcong.http.values;

public class URP {

    // 主机地址
    public static final String BASE_URL = "http://60.219.165.24";
    public static final String PAGE_MAIN_URL = BASE_URL + "/menu/mainFrame.jsp";
    // 登录地址
    public static final String URP_URL = "http://60.219.165.24/loginAction.do";
    // 顶部导航菜单URL
    public static final String MENU_TOP_URL = BASE_URL + "/menu/s_top.jsp";
    // 左侧导航菜单的URL
    public static final String MENU_LEFT_URL = BASE_URL + "/menu/s_menu.jsp";
    // 具体菜单的URL
    public static final String MENU_MAIN_URL = BASE_URL + "/menu/s_main.jsp";
    /** 全部及格成绩 */
    public static final String INFO_QB_JG_URL = BASE_URL + "/gradeLnAllAction.do?type=ln&oper=qb";
    /** 获取每一个学期的数据 */
    public static final String INFO_QB_LNXNDM_URL = BASE_URL + "/gradeLnAllAction.do?type=ln&oper=qbinfo";
    /** 按课程属性成绩查询 菜单 */
    public static final String INFO_SX_MENU_URL = BASE_URL + "/gradeLnAllAction.do?type=ln&oper=sx";
    /** 按课程属性成绩查询 结果 */
    public static final String INFO_SX_URL = BASE_URL + "/gradeLnAllAction.do?type=ln&oper=sxinfo&lnsxdm=001";
    /** 按方案成绩查询 */
    public static final String INFO_FA_URL = BASE_URL + "/gradeLnAllAction.do?type=ln&oper=fainfo&fajhh=2597";
    /** 不及格成绩 */
    public static final String INFO_BJG_URL = BASE_URL + "/gradeLnAllAction.do?type=ln&oper=bjg";
    /** 本学期成绩查询 */
    public static final String INFO_BXQ_URL = BASE_URL + "/bxqcjcxAction.do";
}

Service类

package com.yellowcong.http.service;

import java.util.List;

import com.yellowcong.http.dto.UserDto;
import com.yellowcong.http.model.Lession;
import com.yellowcong.http.model.User;

public interface UrpService {
    /**
     * 用户登录,获取用户的信息  以及用户能控制的按钮
     * @param dto
     * @return
     */
    User login(UserDto dto);
    /**
     * 获取所有的课程
     * @return
     */
    List<Lession> getLessionScoreAll();

    /**
     * 通过学期的方式来获取数据
     * 我将他改为 获取指定学期  每个学期的成绩
     * 1-2-3-4-5 从 0 开始
     * @return
     */
    List<Lession> getLessionScore(Integer xueqi);

    /**
     * 获取成绩通过 成绩的属性
     * @return
     */
    List<Lession> getLessionScoreByType();


    /**
     * 通过专业属性来查
     * @return
     */
    List<Lession> getLessionScoreByMajor();

    /**
     * 获取所有的学期信息
     * @return
     */
    List<String> getXqInfo();
}

实现类

package com.yellowcong.http.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import com.yellowcong.http.dto.UserDto;
import com.yellowcong.http.model.Lession;
import com.yellowcong.http.model.User;
import com.yellowcong.http.service.UrpService;
import com.yellowcong.http.test.HttpClient;
import com.yellowcong.http.values.URP;
import com.yellowcong.utils.StringUtils;

public class UrpServiceImpl implements UrpService{

    @Override
    public User login(UserDto dto) {
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("zjh", dto.getStudentId());
        map.put("mm",dto.getPasswrod());
        String str = HttpClient.post(URP.URP_URL,map);

        String strTop = HttpClient.get(URP.MENU_TOP_URL);
        //获取到所有的用户的菜单名称
        Document doc = Jsoup.parse(strTop);
        //获取用户菜单
        List<String> menus = getTopMenus(doc);
        //获取用户名称
        String username = getUserName(doc);

        User user = new User();
        user.setPassword(dto.getPasswrod());
        user.setStudentId(dto.getStudentId());
        user.setUsername(username);
        user.setTopMenu(menus);

        return user;
    }

    /**
     * 获取同学的学期信息,一个学期就是一个成绩啊
     * 获取同学们的学期
     *  2012-2013学年第一学期(两学期)
        2012-2013学年第二学期(两学期)
        2013-2014学年第一学期(两学期)
        2013-2014学年第二学期(两学期)
        2014-2015学年第一学期(两学期)
        2014-2015学年第二学期(两学期)
        2015-2016学年第一学期(两学期)
        2015-2016学年第二学期(两学期) 
     * @return
     */
    public List<String> getXqInfo(){
        String quanBuStr = HttpClient.get(URP.INFO_QB_JG_URL);
        Document  quanBu = Jsoup.parse(quanBuStr);
        Element el = quanBu.getElementsByClass("table_k").get(0);
        Elements dataInfo = el.getElementsByTag("table").last().getElementsByTag("a");
        Iterator<Element> its = dataInfo.iterator();
        List<String> list = new ArrayList<String>();
        while(its.hasNext()){
            list.add(its.next().html());
        }
        return list;
    }

    /**
     * 移除掉String上面的html数据
     * @param el
     * @return
     */
    private String formatStr(Element el){
         //去掉html的样式
         String info = StringUtils.removeHtmlTags(el.html());
         return StringUtils.removeHtmlNull(info);
    }

    /**
     * 设定学习数据消息  
     * @param lnx
     * @param xueqiNms
     * @param xueqi
     * @return
     */
    private List<Lession> setLession(Element lnx,String xqNames){
        List<Lession> lessions = new ArrayList<Lession>();

        //获取每个学期的表头,表头固定的,所以没有动
        Elements xqEl = lnx.getElementsByTag("thead").get(0).getElementsByTag("th");
        Iterator<Element> xqElIt = xqEl.iterator();

        //获取每个学期的成绩
        Elements scorEl = lnx.getElementsByTag("tbody").first().getElementsByTag("tr");
        Iterator<Element> scorIt = scorEl.iterator();
        while(scorIt.hasNext()){
             //获取一个课程的所有信息
             Elements lessionEls = scorIt.next().getElementsByTag("td");

             Lession les = new Lession();

             //学期
             les.setXueqi(xqNames);
             //课程号
             les.setCode(formatStr(lessionEls.get(0)));
             //课序号
             les.setNumber(formatStr(lessionEls.get(1)));
             //课程名 
             les.setCnName(formatStr(lessionEls.get(2)));
             //英文课程名 
             les.setEnName(formatStr(lessionEls.get(3)));
             // 学分
             les.setCredit(formatStr(lessionEls.get(4)));
             //课程属性
             les.setType(formatStr(lessionEls.get(5)));
             //成绩
             les.setScore(formatStr(lessionEls.get(6)));
             if(xqNames == null || "".equals(xqNames)){
                 //未通过原因 
                 les.setResion(formatStr(lessionEls.get(7)));
             }
             //添加数据
             lessions.add(les);
        }
        return lessions;
    }
    /**
     * 这个破玩意人家设计的时候,就是将所有的学期的数据都发送给我们
     * @return
     */
    public List<Lession> getLessionScoreAll(){
        return this.getLessionScore(null);

    }
    /**
     * 获取每个学期成绩的url
     * gradeLnAllAction.do?type=ln&oper=qbinfo&lnxndm=2015-2016学年第二学期(两学期)#qb_2015-2016学年第二学期(两学期)
     * @param xueqi
     * @return
     */
    private String getLnxndmUrl(String xueqi){
        return URP.INFO_QB_LNXNDM_URL+"&lnxndm="+xueqi+"#qb_"+xueqi;
    }
    /**
     * 获取用户的名称
     * @param doc
     * @return
     */
    private static String getUserName(Document doc){
        //获取用户的信息
        Element userInfo=doc.getElementsByClass("leftuser01").get(0);
        String userNameStr =userInfo.select("tr").first().text();
        userNameStr = userNameStr.replace("欢迎光临", "").replace("|", "").replace("注销", "").replaceAll(" ", "").replaceAll(" ", "");
        return userNameStr;
    }
    /**
     * 获取顶部的菜单数据
     * @param doc
     * @return
     */
    private static List<String> getTopMenus(Document doc){
        Elements topMenus= doc.getElementsByTag("A");
        Iterator<Element> it = topMenus.iterator();
        List<String> list = new ArrayList<String>();
        while(it.hasNext()){
            list.add(it.next().html());
        }
        return list;
    }

    @Override
    public List<Lession> getLessionScore(Integer xueqi) {
        List<String> xueqiNms = getXqInfo();
        Integer xueqiNow = null;
        if(xueqi == null){
            xueqiNow = xueqiNms.size()-1;
        }else{
            xueqiNow = xueqi-1;
        }
        //获取访问的url
        String lnxUrl = getLnxndmUrl(xueqiNms.get(xueqiNow));
        List<Lession> lessions = new ArrayList<Lession>();

        //获取学期数据
        String lnxHtml = HttpClient.get(lnxUrl);
        Document lnxDoc = Jsoup.parse(lnxHtml);

        Elements lnxEls = lnxDoc.getElementsByClass("displayTag");


        for(int i=0;i<=xueqiNow;i++){
            Element lnx = lnxEls.get(i);
            //获取这学期的课程
            List<Lession> xqLession = setLession(lnx,xueqiNms.get(i));
            lessions.addAll(xqLession);
        }
        return lessions;
    }

    @Override
    public List<Lession> getLessionScoreByType() {
        //通过属性查询成绩
        String strHtml = HttpClient.get(URP.INFO_SX_URL);
        Document lnxDoc = Jsoup.parse(strHtml);
        Elements lnxEls = lnxDoc.getElementsByClass("displayTag");

        Iterator<Element> lnxIt = lnxEls.iterator();
        List<Lession> lessions = new ArrayList<Lession>();

        while(lnxIt.hasNext()){
            Element lnx =lnxIt.next();
            List<Lession> xqLession = setLession(lnx,"");
            lessions.addAll(xqLession);
        }

        return lessions;
    }

    @Override
    public List<Lession> getLessionScoreByMajor() {
        //通过属性查询成绩
        String strHtml = HttpClient.get(URP.INFO_FA_URL);
        Document lnxDoc = Jsoup.parse(strHtml);
        Elements lnxEls = lnxDoc.getElementsByClass("displayTag");

        Iterator<Element> lnxIt = lnxEls.iterator();
        List<Lession> lessions = new ArrayList<Lession>();

        while(lnxIt.hasNext()){
            Element lnx =lnxIt.next();
            List<Lession> xqLession = setLession(lnx,"");
            lessions.addAll(xqLession);
        }

        return lessions;
    }


}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狂飙的yellowcong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值