diff --git a/README.md b/README.md index 7d4e437..b257769 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,8 @@ 核心代码来自武科大助手后端爬虫模块,在此基础上进行部分修改以适用于各种平台,因此不会使用重量级的框架,尽量保证仅使用原生java或jvm兼容的语言即可使用,是一个比较~~轻量~~的库 +由于处在早期阶段,因此项目结构随时可能发生巨大变化,在正式版出来前请勿重度依赖 + ~~(说白了就是一个爬虫库,只不过泛用性高,在任何jvm平台上都能使用,而不仅限于spring体系)~~ 后续可能会根据需要新增其他语言的实现以提供给其他语言和平台的使用 diff --git a/mywust-core/pom.xml b/mywust-core/pom.xml index 152ba96..824bc92 100644 --- a/mywust-core/pom.xml +++ b/mywust-core/pom.xml @@ -34,6 +34,20 @@ jregex 1.2_01 + + + + org.jsoup + jsoup + 1.15.3 + + + + cn.linghang + mywust-model + 0.0.1-dev + compile + diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/api/Bkjx.java b/mywust-core/src/main/java/cn/linghang/mywust/core/api/Bkjx.java index f93e10a..375cdec 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/api/Bkjx.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/api/Bkjx.java @@ -12,6 +12,8 @@ public class Bkjx { public static final String BKJX_TEST_API = "http://bkjx.wust.edu.cn/jsxsd/xxwcqk/xxwcqk_idxOnzh.do"; + public static final String BKJX_STUDENT_INFO_API = "http://bkjx.wust.edu.cn/jsxsd/grxx/xsxx"; + public static class Legacy { public static final String BKJX_INDEX = "http://bkjx.wust.edu.cn"; public static final String BKJX_DATA_STRING_API = "http://bkjx.wust.edu.cn/Logon.do?method=logon&flag=sess"; diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/api/UnionAuth.java b/mywust-core/src/main/java/cn/linghang/mywust/core/api/UnionAuth.java index 93f7cf1..bd869a0 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/api/UnionAuth.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/api/UnionAuth.java @@ -6,7 +6,10 @@ public class UnionAuth { */ public static final String UNION_AUTH_API = "https://auth.wust.edu.cn/lyuapServer/v1/tickets"; - public static final String LIBRARY_SSO_SERVICE = "https://libsys.wust.edu.cn:443/meta-local/opac/cas/rosetta"; + public static class Service { - public static final String BKJX_SSO_SERVICE = "http://bkjx.wust.edu.cn/jsxsd/sso.jsp"; + public static final String LIBRARY_SSO_SERVICE = "https://libsys.wust.edu.cn:443/meta-local/opac/cas/rosetta"; + + public static final String BKJX_SSO_SERVICE = "http://bkjx.wust.edu.cn/jsxsd/sso.jsp"; + } } diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/exception/CookieInvalidException.java b/mywust-core/src/main/java/cn/linghang/mywust/core/exception/CookieInvalidException.java new file mode 100644 index 0000000..8b037e5 --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/exception/CookieInvalidException.java @@ -0,0 +1,4 @@ +package cn.linghang.mywust.core.exception; + +public class CookieInvalidException extends BasicException { +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/exception/HtmlPageParseException.java b/mywust-core/src/main/java/cn/linghang/mywust/core/exception/HtmlPageParseException.java new file mode 100644 index 0000000..8bd82cd --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/exception/HtmlPageParseException.java @@ -0,0 +1,4 @@ +package cn.linghang.mywust.core.exception; + +public class HtmlPageParseException extends BasicException { +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/parser/Parser.java b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/Parser.java new file mode 100644 index 0000000..0c4d137 --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/Parser.java @@ -0,0 +1,7 @@ +package cn.linghang.mywust.core.parser; + +import cn.linghang.mywust.core.exception.HtmlPageParseException; + +public interface Parser { + public T parse(String html) throws HtmlPageParseException; +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/StudentInfoPageParser.java b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/StudentInfoPageParser.java new file mode 100644 index 0000000..c7c99e3 --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/StudentInfoPageParser.java @@ -0,0 +1,64 @@ +package cn.linghang.mywust.core.parser.undergraduate; + +import cn.linghang.mywust.core.exception.HtmlPageParseException; +import cn.linghang.mywust.core.parser.Parser; +import cn.linghang.mywust.core.parser.undergraduate.xpath.StudentInfoXpath; +import cn.linghang.mywust.model.undergrade.StudentInfo; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + +public class StudentInfoPageParser implements Parser { + + public StudentInfo parse(String html) throws HtmlPageParseException { + Document page = Jsoup.parse(html); + Element table = page.getElementById("xjkpTable"); + if (table == null) { + throw new HtmlPageParseException(); + } + + Elements studentElements = table.selectXpath(StudentInfoXpath.STUDENT_NUMBER); + String studentNumber = studentElements.isEmpty() ? null : studentElements.get(0).text().replace("学号:", ""); + + Elements collegeElements = table.selectXpath(StudentInfoXpath.COLLEGE); + String college = collegeElements.isEmpty() ? null : collegeElements.get(0).text().replace("院系:", ""); + + Elements majorElements = table.selectXpath(StudentInfoXpath.MAJOR); + String major = majorElements.isEmpty() ? null : majorElements.get(0).text().replace("专业:", ""); + + Elements classElements = table.selectXpath(StudentInfoXpath.CLASS); + String clazz = classElements.isEmpty() ? null : classElements.get(0).text().replace("班级:", ""); + + Elements nameElements = table.selectXpath(StudentInfoXpath.NAME); + String name = nameElements.isEmpty() ? null : nameElements.get(0).text(); + + Elements sexElements = table.selectXpath(StudentInfoXpath.SEX); + String sex = sexElements.isEmpty() ? null : sexElements.get(0).text(); + + Elements birthdayElements = table.selectXpath(StudentInfoXpath.BIRTHDAY); + String birthday = birthdayElements.isEmpty() ? null : birthdayElements.get(0).text(); + + Elements hometownElements = table.selectXpath(StudentInfoXpath.HOMETOWN); + String hometown = hometownElements.isEmpty() ? null : hometownElements.get(0).text(); + + Elements nationalityElements = table.selectXpath(StudentInfoXpath.NATIONALITY); + String nationality = nationalityElements.isEmpty() ? null : nationalityElements.get(0).text(); + + Elements idNumberElements = table.selectXpath(StudentInfoXpath.ID_NUMBER); + String idNumber = idNumberElements.isEmpty() ? null : idNumberElements.get(0).text(); + + return StudentInfo.builder() + .studentNumber(studentNumber) + .college(college) + .major(major) + .clazz(clazz) + .name(name) + .sex(sex) + .birthday(birthday) + .hometown(hometown) + .nationality(nationality) + .idNumber(idNumber) + .build(); + } +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/xpath/StudentInfoXpath.java b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/xpath/StudentInfoXpath.java new file mode 100644 index 0000000..54d9704 --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/parser/undergraduate/xpath/StudentInfoXpath.java @@ -0,0 +1,31 @@ +package cn.linghang.mywust.core.parser.undergraduate.xpath; + +/** + *

本科生学生信息接口用到的xpath

+ *

看着挺唬人的,其实直接浏览器选择元素复制xpath就行了

+ *

这里的xpath只要网站UI不整什么花活就不会出问题

+ * + * @author lensfrex + * @create 2022-10-22 22:16 + */ +public class StudentInfoXpath { + public static final String STUDENT_NUMBER = "//*[@id=\"xjkpTable\"]/tbody/tr[3]/td[5]"; + + public static final String COLLEGE = "//*[@id=\"xjkpTable\"]/tbody/tr[3]/td[1]"; + + public static final String MAJOR = "//*[@id=\"xjkpTable\"]/tbody/tr[3]/td[2]"; + + public static final String CLASS = "//*[@id=\"xjkpTable\"]/tbody/tr[3]/td[4]"; + + public static final String NAME = "//*[@id=\"xjkpTable\"]/tbody/tr[4]/td[2]"; + + public static final String SEX = "//*[@id=\"xjkpTable\"]/tbody/tr[4]/td[4]"; + + public static final String BIRTHDAY = "//*[@id=\"xjkpTable\"]/tbody/tr[5]/td[2]"; + + public static final String HOMETOWN = "//*[@id=\"xjkpTable\"]/tbody/tr[7]/td[2]"; + + public static final String NATIONALITY = "//*[@id=\"xjkpTable\"]/tbody/tr[8]/td[4]"; + + public static final String ID_NUMBER = "//*[@id=\"xjkpTable\"]/tbody/tr[50]/td[4]"; +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/AuthRequestFactory.java b/mywust-core/src/main/java/cn/linghang/mywust/core/request/AuthRequestFactory.java similarity index 92% rename from mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/AuthRequestFactory.java rename to mywust-core/src/main/java/cn/linghang/mywust/core/request/AuthRequestFactory.java index 824fd9f..f9d9da2 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/AuthRequestFactory.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/request/AuthRequestFactory.java @@ -1,8 +1,7 @@ -package cn.linghang.mywust.core.service.auth; +package cn.linghang.mywust.core.request; import cn.linghang.mywust.core.api.UnionAuth; import cn.linghang.mywust.network.HttpRequest; -import cn.linghang.mywust.network.RequestFactory; import cn.linghang.mywust.util.StringUtil; import java.nio.charset.StandardCharsets; diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/BkjxAuthRequestFactory.java b/mywust-core/src/main/java/cn/linghang/mywust/core/request/BkjxRequestFactory.java similarity index 84% rename from mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/BkjxAuthRequestFactory.java rename to mywust-core/src/main/java/cn/linghang/mywust/core/request/BkjxRequestFactory.java index e5dc8a2..f2ca8e8 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/BkjxAuthRequestFactory.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/request/BkjxRequestFactory.java @@ -1,19 +1,22 @@ -package cn.linghang.mywust.core.service.undergraduate; +package cn.linghang.mywust.core.request; import cn.linghang.mywust.core.api.Bkjx; import cn.linghang.mywust.network.HttpRequest; -import cn.linghang.mywust.network.RequestFactory; import cn.linghang.mywust.util.StringUtil; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; -public class BkjxAuthRequestFactory extends RequestFactory { +public class BkjxRequestFactory extends RequestFactory { public static HttpRequest sessionCookieRequest(String serviceTicket) { return makeHttpRequest(String.format(Bkjx.BKJX_SESSION_COOKIE_API, serviceTicket)); } + public static HttpRequest studentInfoRequest(String cookies) { + return makeHttpRequest(Bkjx.BKJX_STUDENT_INFO_API, null, cookies); + } + public static class Legacy { public static HttpRequest dataStringRequest() { return makeHttpRequest(Bkjx.Legacy.BKJX_DATA_STRING_API); diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/library/LibraryAuthRequestFactory.java b/mywust-core/src/main/java/cn/linghang/mywust/core/request/LibraryRequestFactory.java similarity index 70% rename from mywust-core/src/main/java/cn/linghang/mywust/core/service/library/LibraryAuthRequestFactory.java rename to mywust-core/src/main/java/cn/linghang/mywust/core/request/LibraryRequestFactory.java index 4aff6bf..66310fe 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/library/LibraryAuthRequestFactory.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/request/LibraryRequestFactory.java @@ -1,10 +1,9 @@ -package cn.linghang.mywust.core.service.library; +package cn.linghang.mywust.core.request; import cn.linghang.mywust.core.api.Library; import cn.linghang.mywust.network.HttpRequest; -import cn.linghang.mywust.network.RequestFactory; -public class LibraryAuthRequestFactory extends RequestFactory { +public class LibraryRequestFactory extends RequestFactory { public static HttpRequest sessionCookieRequest(String serviceTicket) { return makeHttpRequest(String.format(Library.LIBRARY_SESSION_COOKIE_API, serviceTicket)); } diff --git a/mywust-network/src/main/java/cn/linghang/mywust/network/RequestFactory.java b/mywust-core/src/main/java/cn/linghang/mywust/core/request/RequestFactory.java similarity index 90% rename from mywust-network/src/main/java/cn/linghang/mywust/network/RequestFactory.java rename to mywust-core/src/main/java/cn/linghang/mywust/core/request/RequestFactory.java index 67d3b15..0564127 100644 --- a/mywust-network/src/main/java/cn/linghang/mywust/network/RequestFactory.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/request/RequestFactory.java @@ -1,4 +1,6 @@ -package cn.linghang.mywust.network; +package cn.linghang.mywust.core.request; + +import cn.linghang.mywust.network.HttpRequest; import java.net.URL; diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/JwcLogin.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/JwcLogin.java similarity index 85% rename from mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/JwcLogin.java rename to mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/JwcLogin.java index 53066f4..5e0eb4b 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/JwcLogin.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/JwcLogin.java @@ -1,10 +1,10 @@ -package cn.linghang.mywust.core.service.undergraduate; +package cn.linghang.mywust.core.service.auth; import cn.linghang.mywust.core.api.Bkjx; import cn.linghang.mywust.core.api.UnionAuth; import cn.linghang.mywust.core.exception.BasicException; import cn.linghang.mywust.core.exception.PasswordWornException; -import cn.linghang.mywust.core.service.auth.UnionLogin; +import cn.linghang.mywust.core.request.BkjxRequestFactory; import cn.linghang.mywust.network.HttpRequest; import cn.linghang.mywust.network.HttpResponse; import cn.linghang.mywust.network.RequestClientOption; @@ -37,7 +37,7 @@ public class JwcLogin { @Deprecated public String getLoginCookieLegacy(String username, String password, RequestClientOption requestOption) throws IOException, BasicException { // 获取某段神秘的dataStr(反正官网代码是这么叫的) - HttpRequest dataStringRequest = BkjxAuthRequestFactory.Legacy.dataStringRequest(); + HttpRequest dataStringRequest = BkjxRequestFactory.Legacy.dataStringRequest(); HttpResponse dataStringResponse = requester.post(dataStringRequest, requestOption); if (dataStringResponse.getBody() == null) { throw new BasicException(); @@ -47,7 +47,7 @@ public class JwcLogin { // 获取登录ticket String encoded = PasswordEncoder.legacyPassword(username, password, dataString); - HttpRequest ticketRequest = BkjxAuthRequestFactory.Legacy.ticketRedirectRequest(encoded); + HttpRequest ticketRequest = BkjxRequestFactory.Legacy.ticketRedirectRequest(encoded); ticketRequest.setCookies(dataStringResponse.getCookies()); HttpResponse ticketResponse = requester.post(ticketRequest, requestOption); @@ -61,7 +61,7 @@ public class JwcLogin { throw new PasswordWornException(); } - HttpRequest sessionRequest = BkjxAuthRequestFactory.makeHttpRequest(sessionRedirect); + HttpRequest sessionRequest = BkjxRequestFactory.makeHttpRequest(sessionRedirect); HttpResponse sessionResponse = requester.get(sessionRequest, requestOption); String cookies = sessionResponse.getCookies(); @@ -73,10 +73,11 @@ public class JwcLogin { } public String getLoginCookie(String username, String password, RequestClientOption requestOption) throws IOException, BasicException { - String serviceTicket = unionLogin.getServiceTicket(username, password, UnionAuth.BKJX_SSO_SERVICE, requestOption); + // 获取service ticket以进行进一步的登录 + String serviceTicket = unionLogin.getServiceTicket(username, password, UnionAuth.Service.BKJX_SSO_SERVICE, requestOption); // 获取登录cookie(session) - HttpRequest sessionRequest = BkjxAuthRequestFactory.sessionCookieRequest(serviceTicket); + HttpRequest sessionRequest = BkjxRequestFactory.sessionCookieRequest(serviceTicket); HttpResponse sessionResponse = requester.get(sessionRequest, requestOption); String cookies = sessionResponse.getCookies(); @@ -97,7 +98,7 @@ public class JwcLogin { "").length(); public boolean checkCookies(String cookies, RequestClientOption option) throws IOException { - HttpRequest testRequest = BkjxAuthRequestFactory.makeHttpRequest(Bkjx.BKJX_TEST_API, null, cookies); + HttpRequest testRequest = BkjxRequestFactory.makeHttpRequest(Bkjx.BKJX_TEST_API, null, cookies); HttpResponse testResponse = requester.get(testRequest, option); // 判断响应长度是否为178个字,登录跳转响应长度 diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/library/LibraryLogin.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/LibraryLogin.java similarity index 74% rename from mywust-core/src/main/java/cn/linghang/mywust/core/service/library/LibraryLogin.java rename to mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/LibraryLogin.java index 408d78b..4a95373 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/library/LibraryLogin.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/LibraryLogin.java @@ -1,9 +1,9 @@ -package cn.linghang.mywust.core.service.library; +package cn.linghang.mywust.core.service.auth; import cn.linghang.mywust.core.api.Library; import cn.linghang.mywust.core.api.UnionAuth; import cn.linghang.mywust.core.exception.BasicException; -import cn.linghang.mywust.core.service.auth.UnionLogin; +import cn.linghang.mywust.core.request.LibraryRequestFactory; import cn.linghang.mywust.network.HttpRequest; import cn.linghang.mywust.network.HttpResponse; import cn.linghang.mywust.network.RequestClientOption; @@ -22,15 +22,16 @@ public class LibraryLogin { } public String getLibraryLoginCookie(String username, String password, RequestClientOption requestOption) throws BasicException, IOException { - String serviceTicket = unionLogin.getServiceTicket(username, password, UnionAuth.LIBRARY_SSO_SERVICE, requestOption); + // 获取service ticket以进行进一步的登录 + String serviceTicket = unionLogin.getServiceTicket(username, password, UnionAuth.Service.LIBRARY_SSO_SERVICE, requestOption); // 获取登录cookie(session) - HttpRequest sessionRequest = LibraryAuthRequestFactory.sessionCookieRequest(serviceTicket); + HttpRequest sessionRequest = LibraryRequestFactory.sessionCookieRequest(serviceTicket); HttpResponse sessionResponse = requester.get(sessionRequest, requestOption); String cookies = sessionResponse.getCookies(); // 请求一次首页 - HttpRequest indexRequest = LibraryAuthRequestFactory.indexRequest(); + HttpRequest indexRequest = LibraryRequestFactory.indexRequest(); indexRequest.setCookies(cookies); requester.get(indexRequest, requestOption); @@ -39,13 +40,11 @@ public class LibraryLogin { public boolean checkCookie(String cookies) throws IOException { RequestClientOption option = RequestClientOption.DEFAULT_OPTION; - - HttpRequest testRequest = LibraryAuthRequestFactory.makeHttpRequest(Library.LIBRARY_COOKIE_TEST_URL); - testRequest.setCookies(cookies); + HttpRequest testRequest = LibraryRequestFactory.makeHttpRequest(Library.LIBRARY_COOKIE_TEST_URL, null, cookies); HttpResponse testResponse = requester.get(testRequest, option); // 响应居然是JSON,好评! - // 但是我们只要看有没有Unauthorized关键字就行了 + // 但是我们只要看是不是Unauthorized就行了 // 未认证的话是Unauthorized(如果人家没有抽风改掉的话) byte[] responseData = testResponse.getBody(); return responseData != null && !new String(responseData).equalsIgnoreCase("Unauthorized"); diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/UnionLogin.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/UnionLogin.java index d99cd19..90c7f80 100644 --- a/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/UnionLogin.java +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/auth/UnionLogin.java @@ -2,6 +2,7 @@ package cn.linghang.mywust.core.service.auth; import cn.linghang.mywust.core.exception.BasicException; import cn.linghang.mywust.core.exception.PasswordWornException; +import cn.linghang.mywust.core.request.AuthRequestFactory; import cn.linghang.mywust.network.HttpRequest; import cn.linghang.mywust.network.HttpResponse; import cn.linghang.mywust.network.RequestClientOption; diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/library/LibraryService.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/library/LibraryService.java new file mode 100644 index 0000000..b589a13 --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/library/LibraryService.java @@ -0,0 +1,4 @@ +package cn.linghang.mywust.core.service.library; + +public class LibraryService { +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/JwcService.java b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/JwcService.java new file mode 100644 index 0000000..5c30c26 --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/service/undergraduate/JwcService.java @@ -0,0 +1,50 @@ +package cn.linghang.mywust.core.service.undergraduate; + +import cn.linghang.mywust.core.exception.CookieInvalidException; +import cn.linghang.mywust.core.exception.HtmlPageParseException; +import cn.linghang.mywust.core.parser.undergraduate.StudentInfoPageParser; +import cn.linghang.mywust.core.request.BkjxRequestFactory; +import cn.linghang.mywust.core.util.BkjxUtil; +import cn.linghang.mywust.model.undergrade.StudentInfo; +import cn.linghang.mywust.network.HttpRequest; +import cn.linghang.mywust.network.HttpResponse; +import cn.linghang.mywust.network.RequestClientOption; +import cn.linghang.mywust.network.Requester; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +public class JwcService { + private static final Logger log = LoggerFactory.getLogger(JwcService.class); + + private final Requester requester; + + private final StudentInfoPageParser studentInfoPageParser; + + public JwcService(Requester requester, StudentInfoPageParser studentInfoPageParser) { + this.requester = requester; + this.studentInfoPageParser = studentInfoPageParser; + } + + public String getStudentInfoPage(String cookies, RequestClientOption requestOption) throws IOException, CookieInvalidException { + HttpRequest request = BkjxRequestFactory.studentInfoRequest(cookies); + HttpResponse response = requester.get(request, requestOption); + + // 检查响应是否正确 + if (response.getBody() == null || + response.getStatusCode() != HttpResponse.HTTP_OK || + BkjxUtil.checkLoginFinger(response.getBody())) { + + throw new CookieInvalidException(); + } + + return new String(response.getBody()); + } + + public StudentInfo getStudentInfo(String cookies, RequestClientOption requestOption) throws IOException, CookieInvalidException, HtmlPageParseException { + String studentInfoPage = this.getStudentInfoPage(cookies, requestOption); + + return studentInfoPageParser.parse(studentInfoPage); + } +} diff --git a/mywust-core/src/main/java/cn/linghang/mywust/core/util/BkjxUtil.java b/mywust-core/src/main/java/cn/linghang/mywust/core/util/BkjxUtil.java new file mode 100644 index 0000000..dac0f53 --- /dev/null +++ b/mywust-core/src/main/java/cn/linghang/mywust/core/util/BkjxUtil.java @@ -0,0 +1,32 @@ +package cn.linghang.mywust.core.util; + +import java.nio.charset.StandardCharsets; + +/** + * 专属于bkjx(本科教学)系统服务的工具类 + */ +public class BkjxUtil { + // 在“Bkjx”系统里边如果收到的响应开头是这个的话多半是cookie无效了,需要重新登录获取cookie + private static final byte[] LOGIN_MESSAGE_RESPONSE_FINGER = "