天天看点

Java实现从学校教务网上爬取数据(一)—— 虚拟登陆第一步:获得post发送的Name 第二步:发送post请求,验证返回的cookie是否正确

<span style="font-family: 'Microsoft YaHei'; font-size: 14px; background-color: rgb(255, 255, 255);">以前看到一些类似课程格子和超级课程表这样的app,感觉都有种高大上的感觉,毕竟可以通过教务网数据从别人的网页上爬到数据,那时的我都不懂这个叫做爬虫程序。这个暑假的课程实践里需要从自家学校的教务网上获取课程表信息,为Android的开发拟写后台的爬虫程序,经过大概一个晚上奋斗,借鉴多方面的资料,最终实现了这个功能,这里把我自己实践过程做一下记录。</span>
           

第一步:获得post发送的Name

这里我需要简单解释一下HTTP协议中get和post这两种表单提交方式的区别。get是从服务器上获取数据,post是向服务器传送数据。get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTP post机制,将表单内各个字段与其内容放置在HTML HEADER内一起传送到ACTION属性所指的URL地址,用户看不到这个过程。从安全性来讲,post比get更安全,而且post的一次传送的数据容量大于get。get一般传送的数据大小一般小于2KB。

一般向密码登陆这样的表单提交方式都是post,如果见过get方式一定要通知我。

用Fidder4抓取得到登录需要传递的参数如下:(不懂Fidder4的百度一下就好)

Java实现从学校教务网上爬取数据(一)—— 虚拟登陆第一步:获得post发送的Name 第二步:发送post请求,验证返回的cookie是否正确

注意到登陆只需要传三个参数userName, password, returnUrl,其中returnUrl为null。 然后我提交NameValuePair的内容就是这样子

List<NameValuePair> nvps = new ArrayList<NameValuePair>();

        nvps.add(new BasicNameValuePair("userName", userName));   
        nvps.add(new BasicNameValuePair("password", password));   
        nvps.add(new BasicNameValuePair("returnUrl", "null"));  
           

第二步:发送post请求,验证返回的cookie是否正确

这一步我就直接贴上代码了

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.Consts;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;

import org.apache.http.message.BasicNameValuePair;

public class AnalogLogin{

	private static final String URL = "xxxxxxxx";//访问的登陆网址

	/** 
	 * 登陆到教务系统 
	 * @author xuan
	 * @param userName 用户名
	 * @param password 密码
	 * @return 成功返回true 失败返回false
	 *  
	 */  
	public boolean login(String userName,String password){  
		HttpClient httpclient = new DefaultHttpClient(new ThreadSafeClientConnManager());


		HttpPost httpost = new HttpPost(URL);  
		List<NameValuePair> nvps = new ArrayList<NameValuePair>();

		nvps.add(new BasicNameValuePair("userName", userName));   
		nvps.add(new BasicNameValuePair("password", password));   
		nvps.add(new BasicNameValuePair("returnUrl", "null"));  
		
		/*设置字符*/  
		httpost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));  
		
		/*尝试登陆*/  
		HttpResponse response;  
		try {     
			response = httpclient.execute(httpost);  
			String result = "";
			Header[] headers = response.getAllHeaders();
			for(Header header: headers)
				result = result + header + "\n";

			System.out.println(result);
			/*验证cookie的内容是否包含userName*/
			if(result.contains(userName)){  
				return true;  
			}else{  
				return false;  
			}  
		} catch (ClientProtocolException e) {  
			e.printStackTrace();  
		} catch (IOException e) {  
			e.printStackTrace();  
		}  

		return false;  
	}



	public static void main(String[]args){
		AnalogLogin login = new AnalogLogin();
		System.out.println(login.login("userName", "password"));
	}


}
           

测试一下,居然成功,说明一晚上的努力还是有成果的,但是登陆成功之后又怎么获取信息,而且不是说登陆成功后要管理header里保存的cookie进行下一次的访问获取吗,但是我上面的代码并没有太多关于获取cookie的内容,算了,睡醒在继续。