前言

前几天有个做校园app的同学让我研究一下怎么爬个人的教务课表,就像课程格子那样导入课程。这里我放出初步的获取课表页html代码的程序,有需要的同学可以拿去用,By the way 听说有个叫Jsoup的开源java库可以解析html代码,你们可以去试试。

代码解释

这里就不解释了吧,我代码里写了注释了,可以直接看注释,另有一部分代码是copy的别人的,自己改了一些,主要是main函数

代码

HttpRequest.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class HttpRequest {
    String url;
    String Cookies;
    HttpURLConnection conn;
    public HttpRequest(String url,String Cookies) {
        // TODO Auto-generated constructor stub
        this.url=url;
        this.Cookies=Cookies;
    }

    /**
     * 向指定URL发送GET方法的请求
     * 
     * @param url
     *            发送请求的URL
     * @param param
     *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return URL 所代表远程资源的响应结果
     */
    public String sendGet(String url, String param) {
        String result = "";
        BufferedReader in = null;
        try {
            String urlNameString = url + "?" + param;
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection connection = realUrl.openConnection();
            // 设置通用的请求属性
            connection
                    .setRequestProperty("accept",
                            "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            // 建立实际的连接
            connection.connect();
            // 获取所有响应头字段
            Map<String, List<String>> map = connection.getHeaderFields();
            // 遍历所有的响应头字段
            for (String key : map.keySet()) {
                System.out.println(key + "--->" + map.get(key));
            }
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送GET请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输入流
        finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 向指定 URL 发送POST方法的请求
     * 
     * @param url
     *            发送请求的 URL
     * @param param
     *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public String sendPost(String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(this.url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept",
                    "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
            conn.setRequestProperty("connection", "Keep-Alive");
            if(this.Cookies!=null)
             conn.setRequestProperty("Cookie",this.Cookies);
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Host", "jw.qdu.edu.cn");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(conn.getOutputStream());
            // 发送请求参数
            out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 获取cookie
            String responseCookie = conn.getHeaderField("Set-Cookie");// 取到所用的Cookie
            //System.out.println(responseCookie);
            this.conn=(HttpURLConnection) conn;
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(
                    conn.getInputStream(), "GBK"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常!" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    public String getCookie() {
        HttpURLConnection h=this.conn;
        return conn.getHeaderField("Set-Cookie");// 取到所用的Cookie
    }
}

Test.java

public class Test {

    public static void main(String[] args) {
        //发送 GET 请求
        //String s=HttpRequest.sendGet("http://jw.qdu.edu.cn/academic/j_acegi_security_check", "key=123&v=456");
       // System.out.println(s);

        //发送 POST 请求

        //任意访问一个页面,获取服务器返回的cookie
        HttpRequest req1=new HttpRequest("http://jw.qdu.edu.cn/academic/index.jsp",null);
        req1.sendPost("");
        String cookies=req1.getCookie();
        System.out.println("cookies:"+cookies);

        //下一步应该要登录,这里已经填好要登录所post的页面,和上边获取到的cookie
        String username="201340704023";
        String pwd="201340704023";
        String captcha="";//验证码,这里我没有实现获取的方式,初步的设想一下应该只要获取那个图片就可以了,我没写界面,所以不好获取,如果有个界面的话,哪怕是个swing应该也挺好获取的。那个图片的地址也只要浏览器打开,F12找一下就可以了。
        HttpRequest req2=new HttpRequest("http://jw.qdu.edu.cn/academic/j_acegi_security_check",cookies);
        //下面的函数参数是post的数据
        String res=req1.sendPost("j_username="+username+"&j_password="+pwd+"&j_captcha="+captcha+"&button1=%B5%C7+%C2%BC");
        System.out.println(res);//要加一个判断,判断是否成功登录
        //登录成功后登录状态是存在cookie里的,所以直接用cookie,访问教务主页或者课表页面就可以获取到当前登录帐号的课表了
        HttpRequest req3=new HttpRequest("http://jw.qdu.edu.cn/academic/student/currcourse/currcourse.jsdo?groupId=&moduleId=2000",cookies);
        String sr=req3.sendPost("");//不需要任何参数
        System.out.println(sr);
        //http://jw.qdu.edu.cn/academic/index_new.jsp
    }
}