-----By Chidori and 乱武-----
这是一个简易的Java版本MOOC网爬虫,可以爬取首页推荐课程的信息。
基本架构为OkHttp3.9.1 + Gson2.8.2, 网页信息通过Fiddler 4分析
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.9.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
下载地址https://www.telerik.com/fiddler (直接百度也可以) 打开之后界面大致如下
选择右侧列表的"JSON"选项,逐个浏览,我们发现名为“/web/j/courseBean.getMocTermStatisticListByParms.rpc?csrfKey=79741ee1fae643aebe52a8261aa84c16”的数据中含有我们需要的课程信息
不过此时不要急着去做,网页很重要的东西不能忘了---Cookie;这里我们看到请求该网页需要很多Cookies,并且请求表单需要一个"csrfKey"的参数
果然我们需要的Cookies就在这里了。另外有意思的是,MOOC的csrf竟然和NTESSTUDYSI这条属性是一样的,降低了我们的代码实现难度。于是只需要先请求一次"/category/all",获取到Cookies和csrfKey,之后带着这些值去请求对应的"/courseBean...." URL即可.
我们需要做的无非是模拟Http请求,获取服务器返回的数据
String url_ = "http://www.icourse163.org/category/all";
client = new OkHttpClient.Builder()
//这里添加一个CookieJar用于让程序帮我们自动管理Cookies
.cookieJar(new CookieJar() {
private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>();
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
cookieStore.put(url.host(), cookies);
for (Cookie cookie : cookies) {
if (csrf == null)
csrf = cookie.value();
//获取csrfKey的值
}
}
@Override
public List<Cookie> loadForRequest(HttpUrl url) {
List<Cookie> cookies = cookieStore.get(url.host());
return cookies != null ? cookies : new ArrayList<Cookie>();
}
})
.build();
Request request = new Request.Builder()
.url(url_)
.build();
Response response = null;
try {
response = client.newCall(request).execute();
} catch (Exception e) {
e.printStackTrace();
}
public String requestInfo() {
RequestBody body = new FormBody.Builder()
.add("csrfKey", csrf)
.build();
Request request = new Request.Builder()
.url(host + csrf)
//注意地址中含有第一步中的csrf
.post(body)
.build();
Response response = null;
try {
response = client.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
如果没有使用过Gson,通过Maven添加依赖之后,在IDEA点开File-->Settings-->Plugins,在Browse repositories中搜索"GsonFormat",点击安装(由于我已经安装过了所以右侧没有那个绿色的Install)
这里建议不要改变量名字了,毕竟是一一对应的,如果擅自修改会改出问题如果必须要修改变量名,请务必上面加上@SerializedName(原Json属性名字)
最后一步解析很简单,直接调用Gson的方法即可,传入之前创建的类
private void decode(String str) {
Gson gson = new Gson();
GsonProcessor processor = gson.fromJson(str, GsonProcessor.class);
ArrayList<ResultBean> beans = (ArrayList<ResultBean>) processor.getResult();
for (ResultBean bean : beans) {
System.out.println("课程id : " + bean.getCourseId());
System.out.println("课程名字 : " + bean.getCourseName());
System.out.println("学校 : " + bean.getSchoolName() + " (" + bean.getSchoolShortName() + ")");
System.out.println("学期id : " + bean.getTermId());
System.out.println("已选人数 : " + bean.getEnrollCount());
System.out.println("图像url : " + bean.getImgUrl());
System.out.println();
}
}
-
我的Github地址:https://github.com/Superplasma
-
乱武Github地址:https://www.github.com/pharra