<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的百度一下就好)

注意到登陸隻需要傳三個參數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的内容,算了,睡醒在繼續。