java从网页抓取数据(博客Java实现从学校教务网上爬取数据(一)——虚拟登陆教务网)
优采云 发布时间: 2022-04-17 21:02java从网页抓取数据(博客Java实现从学校教务网上爬取数据(一)——虚拟登陆教务网)
在之前的博客中,我写过虚拟登录教务网是通过HttpClient的post方法实现的。登录成功后,很容易得到课程表。登录的目的是为了获取cookies,但是上一篇的代码好像没有管理cookies。其实httpClient4.x已经开始支持cookies的自动管理,即只要一直使用同一个HttpClient实例,就不需要管理网站返回的cookies . 这种情况下,只需要使用登录时使用的HttpClient实例向课程表所在的页面发送get请求,即可跳转到课程表的页面。
第一步:跳转到课表页面
既然已经获取了cookie实例,不懂的可以参考我之前的博客Java爬取学校教务网站的数据(一)--虚拟登录,可以直接发起get请求进入网页课程所在的位置)
/*检查是否已经登陆成功*/
if(httpClient==null)
return null;
HttpGet httpGet = new HttpGet(SURL);
HttpResponse response;
try {
response = httpClient.execute(httpGet);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
第二步:获取页面的html文本
执行execute()方法后,会返回一个HttpResponse对象,服务器返回的所有信息都会收录在其中。调用 getEntity() 方法获取一个 HttpEntity 实例,然后使用静态方法 EntityUtils.toString 将其转换为 String。
HttpEntity entity = response.getEntity();
String htmlTxt = EntityUtils.toString(entity, "utf-8");//防止出现中文乱码
第三步:使用jsoup对html文本进行简单的过滤整理
虽然已经拿到了课表的信息,但是信息确实是html文本,根本没有太多有用的信息。
这时候就需要使用jsoup对这些文本进行过滤,提取有用信息,封装成类
我根据我校教务网的课程内容做了一个简单的提取,合成了一个类
class ScheduleItem {
private String id; //课程ID
private String name; //课程名
private String message;
private String teachers; //课程老师
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getTeachers() {
return teachers;
}
public void setTeachers(String teachers) {
this.teachers = teachers;
}
}
通过jsoup过滤和封装课程类的代码如下:
schedule = new ArrayList();
Document doc = Jsoup.parse(htmlTxt);
Elements trs = doc.select("table").select("tr");
for(int i = 3;i < trs.size() - 1;i++){
Elements tds = trs.get(i).select("td");
ScheduleItem item = new ScheduleItem();
item.setId(tds.get(0).text());
item.setName(tds.get(2).text());
item.setTeachers(tds.get(4).text());
item.setMessage(tds.get(5).text());
schedule.add(item);
}
整个函数类的代码如下:
<p>import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
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.HttpGet;
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;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
public class AnalogLogin{
private static final String URL = "xxxxxx";//访问的登陆网址
private static final String SURL = "xxxxxx";//课程表所在网址
private static HttpClient httpClient;
/**
* 登陆到教务系统
* @author xuan
* @param userName 用户名
* @param password 密码
* @return 成功返回true 失败返回false
*
*/
public boolean login(String userName,String password){
httpClient = new DefaultHttpClient(new ThreadSafeClientConnManager());
HttpPost httpost = new HttpPost(URL);
List nvps = new ArrayList();
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);
/*验证是否请求和响应都成功*/
if(response.getStatusLine().getStatusCode() == 200){
return true;
}else{
httpClient = null;
return false;
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public List getSchedule(){
/*检查是否已经登陆成功*/
if(httpClient==null)
return null;
HttpGet httpGet = new HttpGet(SURL);
HttpResponse response;
try {
response = httpClient.execute(httpGet);
String htmlTxt = null;
/*验证是否请求和响应都成功*/
if(response.getStatusLine().getStatusCode() == 200){
HttpEntity entity = response.getEntity();
htmlTxt = EntityUtils.toString(entity, "utf-8");
}else {
httpClient = null;
return null;
}
Listschedule = new ArrayList();
Document doc = Jsoup.parse(htmlTxt);
Elements trs = doc.select("table").select("tr");
for(int i = 3;i