Compare commits
9 Commits
036c4b47be
...
0c47043757
Author | SHA1 | Date |
---|---|---|
lensfrex | 0c47043757 | 2 years ago |
lensfrex | ebf06af1a7 | 2 years ago |
lensfrex | 5c94e98269 | 2 years ago |
lensfrex | 4743d9ace0 | 2 years ago |
lensfrex | 12648a7ad0 | 2 years ago |
lensfrex | 950e3ca948 | 2 years ago |
lensfrex | 24c23c33e1 | 2 years ago |
lensfrex | 79c6659509 | 2 years ago |
lensfrex | d6fc6f9878 | 2 years ago |
@ -0,0 +1,17 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<groupId>cn.linghang</groupId> |
||||||
|
<artifactId>mywust</artifactId> |
||||||
|
<version>0.0.1-fixed</version> |
||||||
|
<packaging>pom</packaging> |
||||||
|
<dependencies> |
||||||
|
<dependency> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
<version>1.18.22</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
</project> |
@ -0,0 +1,58 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<groupId>cn.linghang</groupId> |
||||||
|
<artifactId>mywust-core</artifactId> |
||||||
|
<version>0.0.1-fixed</version> |
||||||
|
<dependencies> |
||||||
|
<dependency> |
||||||
|
<groupId>cn.linghang</groupId> |
||||||
|
<artifactId>mywust-network</artifactId> |
||||||
|
<version>0.0.1-fixed</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>cn.linghang</groupId> |
||||||
|
<artifactId>mywust-util</artifactId> |
||||||
|
<version>0.0.1-fixed</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.slf4j</groupId> |
||||||
|
<artifactId>slf4j-api</artifactId> |
||||||
|
<version>2.0.3</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.jsoup</groupId> |
||||||
|
<artifactId>jsoup</artifactId> |
||||||
|
<version>1.15.3</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>cn.linghang</groupId> |
||||||
|
<artifactId>mywust-model</artifactId> |
||||||
|
<version>0.0.1-fixed</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>com.fasterxml.jackson.core</groupId> |
||||||
|
<artifactId>jackson-annotations</artifactId> |
||||||
|
<version>2.14.0-rc1</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>com.fasterxml.jackson.core</groupId> |
||||||
|
<artifactId>jackson-databind</artifactId> |
||||||
|
<version>2.14.0-rc1</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
<version>1.18.22</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
</project> |
@ -1,5 +0,0 @@ |
|||||||
package cn.linghang.mywust.core; |
|
||||||
|
|
||||||
public class Mywust { |
|
||||||
|
|
||||||
} |
|
@ -1,5 +0,0 @@ |
|||||||
package cn.linghang.mywust.core; |
|
||||||
|
|
||||||
public class MywustFactory { |
|
||||||
|
|
||||||
} |
|
@ -1,6 +1,6 @@ |
|||||||
package cn.linghang.mywust.core.api; |
package cn.linghang.mywust.core.api; |
||||||
|
|
||||||
public class Graduate { |
public class GraduateUrls { |
||||||
public static final String GRADUATE_CAPTCHA_API = "http://59.68.177.189/pyxx/PageTemplate/NsoftPage/yzm/createyzm.aspx"; |
public static final String GRADUATE_CAPTCHA_API = "http://59.68.177.189/pyxx/PageTemplate/NsoftPage/yzm/createyzm.aspx"; |
||||||
public static final String GRADUATE_LOGIN_API = "http://59.68.177.189/pyxx/login.aspx"; |
public static final String GRADUATE_LOGIN_API = "http://59.68.177.189/pyxx/login.aspx"; |
||||||
|
|
@ -1,6 +1,6 @@ |
|||||||
package cn.linghang.mywust.core.api; |
package cn.linghang.mywust.core.api; |
||||||
|
|
||||||
public class Library { |
public class LibraryUrls { |
||||||
public static final String LIBRARY_SESSION_COOKIE_API = "https://libsys.wust.edu.cn/meta-local/opac/cas/rosetta?ticket=%s"; |
public static final String LIBRARY_SESSION_COOKIE_API = "https://libsys.wust.edu.cn/meta-local/opac/cas/rosetta?ticket=%s"; |
||||||
|
|
||||||
public static final String LIBRARY_INDEX_URL = "https://libsys.wust.edu.cn/meta-local/opac/cas/rosetta"; |
public static final String LIBRARY_INDEX_URL = "https://libsys.wust.edu.cn/meta-local/opac/cas/rosetta"; |
@ -1,6 +1,6 @@ |
|||||||
package cn.linghang.mywust.core.api; |
package cn.linghang.mywust.core.api; |
||||||
|
|
||||||
public class PhysicsSystem { |
public class PhysicsSystemUrls { |
||||||
public static final String PHYSICS_LOGIN_INDEX = "http://wlsy.wust.edu.cn/Page/BI/BI000.aspx"; |
public static final String PHYSICS_LOGIN_INDEX = "http://wlsy.wust.edu.cn/Page/BI/BI000.aspx"; |
||||||
|
|
||||||
public static final String PHYSICS_LOGIN_COOKIES_API = "http://wlsy.wust.edu.cn/Page/BI/BI000.aspx"; |
public static final String PHYSICS_LOGIN_COOKIES_API = "http://wlsy.wust.edu.cn/Page/BI/BI000.aspx"; |
@ -1,6 +1,6 @@ |
|||||||
package cn.linghang.mywust.core.api; |
package cn.linghang.mywust.core.api; |
||||||
|
|
||||||
public class UnionAuth { |
public class UnionAuthUrls { |
||||||
/** |
/** |
||||||
* 统一认证登录验证的api地址,请求之后可进一步获取service ticket来对具体的服务进行登录获取Cookies |
* 统一认证登录验证的api地址,请求之后可进一步获取service ticket来对具体的服务进行登录获取Cookies |
||||||
*/ |
*/ |
@ -1,72 +0,0 @@ |
|||||||
package cn.linghang.mywust.core.parser.undergraduate; |
|
||||||
|
|
||||||
import cn.linghang.mywust.core.exception.ParseException; |
|
||||||
import cn.linghang.mywust.core.parser.Parser; |
|
||||||
import cn.linghang.mywust.core.util.JsoupUtil; |
|
||||||
import cn.linghang.mywust.model.global.ExamInfo; |
|
||||||
import org.jsoup.Jsoup; |
|
||||||
import org.jsoup.nodes.Element; |
|
||||||
import org.jsoup.select.Elements; |
|
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
public class ExamInfoParser implements Parser<List<ExamInfo>> { |
|
||||||
private static final Logger log = LoggerFactory.getLogger(ExamInfoParser.class); |
|
||||||
|
|
||||||
@Override |
|
||||||
public List<ExamInfo> parse(String html) throws ParseException { |
|
||||||
Elements rows = Jsoup.parse(html).selectXpath(ExamInfoXpath.EXAM_INFO_ROWS_XPATH); |
|
||||||
if (rows.isEmpty()) { |
|
||||||
throw new ParseException(html); |
|
||||||
} |
|
||||||
|
|
||||||
List<ExamInfo> examInfos = new ArrayList<>(rows.size()); |
|
||||||
|
|
||||||
try { |
|
||||||
for (Element row : rows) { |
|
||||||
// 提取出当前行的所有格子
|
|
||||||
Elements girds = row.getElementsByTag("td"); |
|
||||||
|
|
||||||
// 如果这行格子数少于6个,即到了“成绩”的那个格子就没了,那就没啥意义了,直接跳过,不理了
|
|
||||||
if (girds.size() < 6) { |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
ExamInfo examInfo = new ExamInfo(); |
|
||||||
|
|
||||||
// 这段看着震撼,但其实很丑
|
|
||||||
examInfo.setId(JsoupUtil.getElementContext(girds.get(0))); |
|
||||||
|
|
||||||
examInfo.setTerm(JsoupUtil.getElementContext(girds.get(1))); |
|
||||||
examInfo.setCourseNumber(JsoupUtil.getElementContext(girds.get(2))); |
|
||||||
|
|
||||||
examInfo.setCourseName(JsoupUtil.getElementContext(girds.get(3))); |
|
||||||
examInfo.setGroupName(JsoupUtil.getElementContext(girds.get(4))); |
|
||||||
|
|
||||||
examInfo.setScore(JsoupUtil.getElementContext(girds.get(5))); |
|
||||||
examInfo.setFlag(JsoupUtil.getElementContext(girds.get(6))); |
|
||||||
examInfo.setCredit(JsoupUtil.getElementContext(girds.get(7))); |
|
||||||
examInfo.setCourseHours(JsoupUtil.getElementContext(girds.get(8))); |
|
||||||
examInfo.setGradePoint(JsoupUtil.getElementContext(girds.get(9))); |
|
||||||
|
|
||||||
examInfo.setEvaluateMethod(JsoupUtil.getElementContext(girds.get(11))); |
|
||||||
examInfo.setKind(JsoupUtil.getElementContext(girds.get(12))); |
|
||||||
examInfo.setCourseKind(JsoupUtil.getElementContext(girds.get(13))); |
|
||||||
|
|
||||||
examInfos.add(examInfo); |
|
||||||
} |
|
||||||
} catch (Exception e) { |
|
||||||
log.warn("解析成绩页面时发生错误:{}", e.getMessage()); |
|
||||||
log.warn("终止解析,返回已解析数据"); |
|
||||||
} |
|
||||||
|
|
||||||
return examInfos; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
final class ExamInfoXpath { |
|
||||||
public static final String EXAM_INFO_ROWS_XPATH = "//*[@id=\"dataList\"]/tbody/tr"; |
|
||||||
} |
|
@ -0,0 +1,72 @@ |
|||||||
|
package cn.linghang.mywust.core.parser.undergraduate; |
||||||
|
|
||||||
|
import cn.linghang.mywust.core.exception.ParseException; |
||||||
|
import cn.linghang.mywust.core.parser.Parser; |
||||||
|
import cn.linghang.mywust.core.util.JsoupUtil; |
||||||
|
import cn.linghang.mywust.model.global.Score; |
||||||
|
import org.jsoup.Jsoup; |
||||||
|
import org.jsoup.nodes.Element; |
||||||
|
import org.jsoup.select.Elements; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
public class UndergradScoreParser implements Parser<List<Score>> { |
||||||
|
private static final Logger log = LoggerFactory.getLogger(UndergradScoreParser.class); |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<Score> parse(String html) throws ParseException { |
||||||
|
Elements rows = Jsoup.parse(html).selectXpath(UndergradScoreXpath.EXAM_INFO_ROWS_XPATH); |
||||||
|
if (rows.isEmpty()) { |
||||||
|
throw new ParseException(html); |
||||||
|
} |
||||||
|
|
||||||
|
List<Score> scores = new ArrayList<>(rows.size()); |
||||||
|
|
||||||
|
try { |
||||||
|
for (Element row : rows) { |
||||||
|
// 提取出当前行的所有格子
|
||||||
|
Elements girds = row.getElementsByTag("td"); |
||||||
|
|
||||||
|
// 如果这行格子数少于6个,即到了“成绩”的那个格子就没了,那就没啥意义了,直接跳过,不理了
|
||||||
|
if (girds.size() < 6) { |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
Score score = new Score(); |
||||||
|
|
||||||
|
// 这段看着震撼,但其实很丑
|
||||||
|
score.setId(JsoupUtil.getElementContext(girds.get(0))); |
||||||
|
|
||||||
|
score.setTerm(JsoupUtil.getElementContext(girds.get(1))); |
||||||
|
score.setCourseNumber(JsoupUtil.getElementContext(girds.get(2))); |
||||||
|
|
||||||
|
score.setCourseName(JsoupUtil.getElementContext(girds.get(3))); |
||||||
|
score.setGroupName(JsoupUtil.getElementContext(girds.get(4))); |
||||||
|
|
||||||
|
score.setScore(JsoupUtil.getElementContext(girds.get(5))); |
||||||
|
score.setFlag(JsoupUtil.getElementContext(girds.get(6))); |
||||||
|
score.setCredit(JsoupUtil.getElementContext(girds.get(7))); |
||||||
|
score.setCourseHours(JsoupUtil.getElementContext(girds.get(8))); |
||||||
|
score.setGradePoint(JsoupUtil.getElementContext(girds.get(9))); |
||||||
|
|
||||||
|
score.setEvaluateMethod(JsoupUtil.getElementContext(girds.get(11))); |
||||||
|
score.setKind(JsoupUtil.getElementContext(girds.get(12))); |
||||||
|
score.setCourseKind(JsoupUtil.getElementContext(girds.get(13))); |
||||||
|
|
||||||
|
scores.add(score); |
||||||
|
} |
||||||
|
} catch (Exception e) { |
||||||
|
log.warn("解析成绩页面时发生错误:{}", e.getMessage()); |
||||||
|
log.warn("终止解析,返回已解析数据"); |
||||||
|
} |
||||||
|
|
||||||
|
return scores; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
final class UndergradScoreXpath { |
||||||
|
public static final String EXAM_INFO_ROWS_XPATH = "//*[@id=\"dataList\"]/tbody/tr"; |
||||||
|
} |
@ -1,27 +1,31 @@ |
|||||||
package cn.linghang.mywust.core.request.library; |
package cn.linghang.mywust.core.request.library; |
||||||
|
|
||||||
import cn.linghang.mywust.core.api.Library; |
import cn.linghang.mywust.core.api.LibraryUrls; |
||||||
import cn.linghang.mywust.core.request.RequestFactory; |
import cn.linghang.mywust.core.request.RequestFactory; |
||||||
import cn.linghang.mywust.network.entitys.HttpRequest; |
import cn.linghang.mywust.network.entitys.HttpRequest; |
||||||
|
|
||||||
public class LibraryRequestFactory extends RequestFactory { |
public class LibraryRequestFactory extends RequestFactory { |
||||||
public static HttpRequest sessionCookieRequest(String serviceTicket) { |
public static HttpRequest sessionCookieRequest(String serviceTicket) { |
||||||
return makeHttpRequest(String.format(Library.LIBRARY_SESSION_COOKIE_API, serviceTicket)); |
return makeHttpRequest(String.format(LibraryUrls.LIBRARY_SESSION_COOKIE_API, serviceTicket)); |
||||||
} |
} |
||||||
|
|
||||||
public static HttpRequest indexRequest() { |
public static HttpRequest indexRequest() { |
||||||
return makeHttpRequest(Library.LIBRARY_INDEX_URL); |
return makeHttpRequest(LibraryUrls.LIBRARY_INDEX_URL); |
||||||
} |
} |
||||||
|
|
||||||
public static HttpRequest currentLoanRequest(String cookie) { |
public static HttpRequest currentLoanRequest(String cookie) { |
||||||
return makeHttpRequest(Library.LIBRARY_CURRENT_LOAN_API, null, cookie); |
return makeHttpRequest(LibraryUrls.LIBRARY_CURRENT_LOAN_API, null, cookie); |
||||||
} |
} |
||||||
|
|
||||||
public static HttpRequest loanHistoryRequest(String cookie) { |
public static HttpRequest loanHistoryRequest(String cookie) { |
||||||
return makeHttpRequest(Library.LIBRARY_LOAN_HISTORY_API, null, cookie); |
return makeHttpRequest(LibraryUrls.LIBRARY_LOAN_HISTORY_API, null, cookie); |
||||||
} |
} |
||||||
|
|
||||||
public static HttpRequest overdueSoonRequest(String cookie) { |
public static HttpRequest overdueSoonRequest(String cookie) { |
||||||
return makeHttpRequest(Library.LIBRARY_OVERDUE_SOON_API, null, cookie); |
return makeHttpRequest(LibraryUrls.LIBRARY_OVERDUE_SOON_API, null, cookie); |
||||||
|
} |
||||||
|
|
||||||
|
public static HttpRequest bookInfoRequest(String cookie) { |
||||||
|
return makeHttpRequest(LibraryUrls.LIBRARY_OVERDUE_SOON_API, null, cookie); |
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -1,61 +0,0 @@ |
|||||||
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.request.undergrade.BkjxRequestFactory; |
|
||||||
import cn.linghang.mywust.network.RequestClientOption; |
|
||||||
import cn.linghang.mywust.network.Requester; |
|
||||||
import cn.linghang.mywust.network.entitys.HttpRequest; |
|
||||||
import cn.linghang.mywust.network.entitys.HttpResponse; |
|
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
|
|
||||||
import java.io.IOException; |
|
||||||
|
|
||||||
public class JwcLogin { |
|
||||||
private static final Logger log = LoggerFactory.getLogger(JwcLogin.class); |
|
||||||
|
|
||||||
private final Requester requester; |
|
||||||
|
|
||||||
private final UnionLogin unionLogin; |
|
||||||
|
|
||||||
public JwcLogin(Requester requester) { |
|
||||||
this.requester = requester; |
|
||||||
this.unionLogin = new UnionLogin(requester); |
|
||||||
} |
|
||||||
|
|
||||||
public String getLoginCookie(String username, String password, RequestClientOption requestOption) throws IOException, BasicException { |
|
||||||
// 获取service ticket以进行进一步的登录
|
|
||||||
String serviceTicket = unionLogin.getServiceTicket(username, password, UnionAuth.Service.BKJX_SSO_SERVICE, requestOption); |
|
||||||
|
|
||||||
// 获取登录cookie(session)
|
|
||||||
HttpRequest sessionRequest = BkjxRequestFactory.sessionCookieRequest(serviceTicket); |
|
||||||
HttpResponse sessionResponse = requester.get(sessionRequest, requestOption); |
|
||||||
|
|
||||||
String cookies = sessionResponse.getCookies(); |
|
||||||
if (roughCheckCookie(cookies)) { |
|
||||||
throw new BasicException(); |
|
||||||
} |
|
||||||
|
|
||||||
return cookies; |
|
||||||
} |
|
||||||
|
|
||||||
private boolean roughCheckCookie(String cookies) { |
|
||||||
return cookies == null || !cookies.contains("JSESSIONID") || !cookies.contains("SERVERID"); |
|
||||||
} |
|
||||||
|
|
||||||
private static final int COOKIES_ERROR_RESPONSE_LENGTH = |
|
||||||
("<script languge='javascript'>window.location.href='https://auth.wust.edu.cn/lyuapServer/login?service=http%3A%2F%2Fbkjx.wust.edu.cn%2Fjsxsd%2Fframework%2FblankPage.jsp'</script>") |
|
||||||
.length(); |
|
||||||
|
|
||||||
public boolean checkCookies(String cookies, RequestClientOption option) throws IOException { |
|
||||||
HttpRequest testRequest = BkjxRequestFactory.makeHttpRequest(Bkjx.BKJX_TEST_API, null, cookies); |
|
||||||
HttpResponse testResponse = requester.get(testRequest, option); |
|
||||||
|
|
||||||
// 判断响应长度是否为这么多个字,登录跳转响应长度
|
|
||||||
// 这种办法虽然在极端情况下可能会出错(而且还挺蠢的),但是是最快的办法中比较准确的了
|
|
||||||
return testResponse.getBody().length != COOKIES_ERROR_RESPONSE_LENGTH; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,116 @@ |
|||||||
|
package cn.linghang.mywust.core.service.auth; |
||||||
|
|
||||||
|
import cn.linghang.mywust.core.api.UndergradUrls; |
||||||
|
import cn.linghang.mywust.core.api.UnionAuthUrls; |
||||||
|
import cn.linghang.mywust.core.exception.ApiException; |
||||||
|
import cn.linghang.mywust.core.request.undergrade.BkjxRequestFactory; |
||||||
|
import cn.linghang.mywust.network.RequestClientOption; |
||||||
|
import cn.linghang.mywust.network.Requester; |
||||||
|
import cn.linghang.mywust.network.entitys.HttpRequest; |
||||||
|
import cn.linghang.mywust.network.entitys.HttpResponse; |
||||||
|
import cn.linghang.mywust.util.PasswordEncoder; |
||||||
|
import org.slf4j.Logger; |
||||||
|
import org.slf4j.LoggerFactory; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
public class UndergraduateLogin { |
||||||
|
private static final Logger log = LoggerFactory.getLogger(UndergraduateLogin.class); |
||||||
|
|
||||||
|
private final Requester requester; |
||||||
|
|
||||||
|
private final UnionLogin unionLogin; |
||||||
|
|
||||||
|
public UndergraduateLogin(Requester requester) { |
||||||
|
this.requester = requester; |
||||||
|
this.unionLogin = new UnionLogin(requester); |
||||||
|
} |
||||||
|
|
||||||
|
public String getLoginCookie(String username, String password, RequestClientOption requestOption) throws IOException, ApiException { |
||||||
|
// 获取service ticket以进行进一步的登录
|
||||||
|
String serviceTicket = unionLogin.getServiceTicket(username, password, UnionAuthUrls.Service.BKJX_SSO_SERVICE, requestOption); |
||||||
|
|
||||||
|
// 获取登录cookie(session)
|
||||||
|
HttpRequest sessionRequest = BkjxRequestFactory.sessionCookieRequest(serviceTicket); |
||||||
|
HttpResponse sessionResponse = requester.get(sessionRequest, requestOption); |
||||||
|
|
||||||
|
String cookies = sessionResponse.getCookies(); |
||||||
|
if (!roughCheckCookie(cookies)) { |
||||||
|
log.error("[mywust]: Cookie粗查不通过:{}", cookies); |
||||||
|
throw new ApiException(ApiException.Code.UNKNOWN_EXCEPTION, "登录获取的Cookie无效"); |
||||||
|
} |
||||||
|
|
||||||
|
// 检查Cookie是否真正可用,同时请求一次任意接口使后续接口能够正确响应
|
||||||
|
// 拿到Cookie后调用的第一个接口会产生302/301跳转,需要再次调用才能正确响应
|
||||||
|
if (!checkCookies(cookies, requestOption)) { |
||||||
|
log.warn("[mywust]: Cookie检查不通过:{}", cookies); |
||||||
|
} |
||||||
|
|
||||||
|
return cookies; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* <p>旧版的登录方式,既相当于直接登录<a href="http://bkjx.wust.edu.cn">bkjx系统</a>,不建议使用</p> |
||||||
|
* <p>注意,这种登录方式的密码和新版可能是不一样的</p> |
||||||
|
* <p>不过不论使用哪种登录方式获取到的cookie都是可用的</p> |
||||||
|
* |
||||||
|
* @return 获取到的Cookies |
||||||
|
*/ |
||||||
|
@Deprecated |
||||||
|
public String getLoginCookieLegacy(String username, String password, RequestClientOption requestOption) throws IOException, ApiException { |
||||||
|
// 获取某段神秘的dataStr(反正官网代码是这么叫的)
|
||||||
|
HttpRequest dataStringRequest = BkjxRequestFactory.Legacy.dataStringRequest(); |
||||||
|
HttpResponse dataStringResponse = requester.post(dataStringRequest, requestOption); |
||||||
|
if (dataStringResponse.getBody() == null) { |
||||||
|
log.warn("[mywust]: 本科教学系统旧版登录方式:获取dataStr时发生错误"); |
||||||
|
throw new ApiException(ApiException.Code.UNKNOWN_EXCEPTION); |
||||||
|
} |
||||||
|
|
||||||
|
String dataString = new String(dataStringResponse.getBody()); |
||||||
|
|
||||||
|
// 获取登录ticket
|
||||||
|
String encoded = PasswordEncoder.legacyPassword(username, password, dataString); |
||||||
|
HttpRequest ticketRequest = BkjxRequestFactory.Legacy.ticketRedirectRequest(encoded); |
||||||
|
ticketRequest.setCookies(dataStringResponse.getCookies()); |
||||||
|
|
||||||
|
HttpResponse ticketResponse = requester.post(ticketRequest, requestOption); |
||||||
|
if (ticketResponse.getBody() == null) { |
||||||
|
log.warn("[mywust]: 本科教学系统旧版登录方式:获取登录ticket时发生错误"); |
||||||
|
throw new ApiException(ApiException.Code.UNKNOWN_EXCEPTION); |
||||||
|
} |
||||||
|
|
||||||
|
// 使用跳转得到的链接获取cookies
|
||||||
|
String sessionRedirect = ticketResponse.getHeaders().get("Location"); |
||||||
|
if (sessionRedirect == null) { |
||||||
|
throw new ApiException(ApiException.Code.BKJX_LEGACY_LOGIN_PASSWORD_WRONG); |
||||||
|
} |
||||||
|
|
||||||
|
HttpRequest sessionRequest = BkjxRequestFactory.makeHttpRequest(sessionRedirect); |
||||||
|
HttpResponse sessionResponse = requester.get(sessionRequest, requestOption); |
||||||
|
|
||||||
|
String cookies = sessionResponse.getCookies(); |
||||||
|
if (checkCookies(cookies, requestOption)) { |
||||||
|
log.warn("[mywust]: Cookie检查不通过:{}", cookies); |
||||||
|
throw new ApiException(ApiException.Code.UNKNOWN_EXCEPTION, "登录获取的Cookie无效"); |
||||||
|
} |
||||||
|
|
||||||
|
return cookies; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean roughCheckCookie(String cookies) { |
||||||
|
return cookies != null && cookies.contains("JSESSIONID") && cookies.contains("SERVERID"); |
||||||
|
} |
||||||
|
|
||||||
|
private static final int COOKIES_ERROR_RESPONSE_LENGTH = |
||||||
|
("<script languge='javascript'>window.location.href='https://auth.wust.edu.cn/lyuapServer/login?service=http%3A%2F%2Fbkjx.wust.edu.cn%2Fjsxsd%2Fframework%2FblankPage.jsp'</script>") |
||||||
|
.length(); |
||||||
|
|
||||||
|
public boolean checkCookies(String cookies, RequestClientOption option) throws IOException { |
||||||
|
HttpRequest testRequest = BkjxRequestFactory.makeHttpRequest(UndergradUrls.BKJX_TEST_API, null, cookies); |
||||||
|
HttpResponse testResponse = requester.get(testRequest, option); |
||||||
|
|
||||||
|
// 判断响应长度是否为这么多个字,登录跳转响应长度
|
||||||
|
// 这种办法虽然在极端情况下可能会出错(而且还挺蠢的),但是是最快的办法中比较准确的了
|
||||||
|
return Math.abs(COOKIES_ERROR_RESPONSE_LENGTH - testResponse.getBody().length) > 8; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,43 @@ |
|||||||
|
package cn.linghang.mywust.core.service.captcha.solver; |
||||||
|
|
||||||
|
import cn.linghang.mywust.captcha.SolvedImageCaptcha; |
||||||
|
import cn.linghang.mywust.captcha.UnsolvedImageCaptcha; |
||||||
|
import cn.linghang.mywust.core.exception.ApiException; |
||||||
|
import cn.linghang.mywust.core.request.RequestFactory; |
||||||
|
import cn.linghang.mywust.network.Requester; |
||||||
|
import cn.linghang.mywust.network.entitys.HttpRequest; |
||||||
|
import cn.linghang.mywust.network.entitys.HttpResponse; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.util.Base64; |
||||||
|
|
||||||
|
public class DdddOcrCaptchaSolver implements CaptchaSolver { |
||||||
|
private final String baseUrl; |
||||||
|
|
||||||
|
private final Requester requester; |
||||||
|
|
||||||
|
public DdddOcrCaptchaSolver(String baseUrl, Requester requester) { |
||||||
|
this.baseUrl = baseUrl; |
||||||
|
this.requester = requester; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public SolvedImageCaptcha solve(UnsolvedImageCaptcha unsolvedImageCaptcha) throws ApiException { |
||||||
|
try { |
||||||
|
SolvedImageCaptcha solvedImageCaptcha = new SolvedImageCaptcha(unsolvedImageCaptcha); |
||||||
|
|
||||||
|
String result = this.ocr(unsolvedImageCaptcha.getImage()); |
||||||
|
solvedImageCaptcha.setResult(result); |
||||||
|
return solvedImageCaptcha; |
||||||
|
} catch (IOException e) { |
||||||
|
throw new ApiException(ApiException.Code.NETWORK_EXCEPTION); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private String ocr(byte[] data) throws IOException { |
||||||
|
HttpRequest request = RequestFactory.makeHttpRequest(baseUrl + "/ocr/b64/text", Base64.getEncoder().encode(data)); |
||||||
|
HttpResponse response = requester.post(request); |
||||||
|
|
||||||
|
return response.getStringBody(); |
||||||
|
} |
||||||
|
} |
@ -1,11 +0,0 @@ |
|||||||
package cn.linghang.mywust.core.service.captcha.solver; |
|
||||||
|
|
||||||
import cn.linghang.mywust.captcha.SolvedImageCaptcha; |
|
||||||
import cn.linghang.mywust.captcha.UnsolvedImageCaptcha; |
|
||||||
|
|
||||||
public class LocalPaddleOcrCaptchaSolver implements CaptchaSolver { |
|
||||||
@Override |
|
||||||
public SolvedImageCaptcha solve(UnsolvedImageCaptcha unsolvedImageCaptcha) { |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
@ -1,33 +0,0 @@ |
|||||||
package cn.linghang.mywust.core.service.undergraduate; |
|
||||||
|
|
||||||
import cn.linghang.mywust.core.exception.ApiException; |
|
||||||
import cn.linghang.mywust.core.exception.ParseException; |
|
||||||
import cn.linghang.mywust.core.parser.undergraduate.CourseTableParser; |
|
||||||
import cn.linghang.mywust.core.request.undergrade.BkjxRequestFactory; |
|
||||||
import cn.linghang.mywust.model.global.Course; |
|
||||||
import cn.linghang.mywust.network.RequestClientOption; |
|
||||||
import cn.linghang.mywust.network.Requester; |
|
||||||
import cn.linghang.mywust.network.entitys.HttpRequest; |
|
||||||
import cn.linghang.mywust.network.entitys.HttpResponse; |
|
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
|
|
||||||
import java.io.IOException; |
|
||||||
import java.util.List; |
|
||||||
|
|
||||||
public class CourseTableApiService extends UndergraduateApiService { |
|
||||||
|
|
||||||
public CourseTableApiService(Requester requester) { |
|
||||||
super(requester); |
|
||||||
} |
|
||||||
|
|
||||||
public String getCourseTablePage(String term, String cookies, RequestClientOption requestClientOption) throws IOException, ApiException { |
|
||||||
HttpRequest request = BkjxRequestFactory.courseTablePageRequest(term, cookies); |
|
||||||
HttpResponse response = requester.post(request, requestClientOption); |
|
||||||
|
|
||||||
super.checkResponse(response); |
|
||||||
|
|
||||||
return new String(response.getBody()); |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,49 @@ |
|||||||
|
package cn.linghang.mywust.core.service.undergraduate; |
||||||
|
|
||||||
|
import cn.linghang.mywust.core.exception.ApiException; |
||||||
|
import cn.linghang.mywust.core.request.undergrade.BkjxRequestFactory; |
||||||
|
import cn.linghang.mywust.network.RequestClientOption; |
||||||
|
import cn.linghang.mywust.network.Requester; |
||||||
|
import cn.linghang.mywust.network.entitys.HttpRequest; |
||||||
|
import cn.linghang.mywust.network.entitys.HttpResponse; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.util.Map; |
||||||
|
|
||||||
|
public class UndergradCourseTableApiService extends UndergradApiServiceBase { |
||||||
|
|
||||||
|
private static final String[] NECESSARY_PARAMS = {"term"}; |
||||||
|
|
||||||
|
public UndergradCourseTableApiService(Requester requester) { |
||||||
|
super(requester); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getPage(String cookie, Map<String, String> params, RequestClientOption option) throws ApiException, IOException { |
||||||
|
for (String key : NECESSARY_PARAMS) { |
||||||
|
if (params.get(key) == null) { |
||||||
|
throw new ApiException(ApiException.Code.PARAM_WRONG_EXCEPTION); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return this.getPage(params.get(NECESSARY_PARAMS[0]), cookie, option); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getPage(String cookie, Map<String, String> params) throws ApiException, IOException { |
||||||
|
return this.getPage(cookie, params, null); |
||||||
|
} |
||||||
|
|
||||||
|
public String getPage(String term, String cookies, RequestClientOption requestClientOption) throws IOException, ApiException { |
||||||
|
HttpRequest request = BkjxRequestFactory.courseTablePageRequest(term, cookies); |
||||||
|
HttpResponse response = requester.post(request, requestClientOption); |
||||||
|
|
||||||
|
super.checkResponse(response); |
||||||
|
|
||||||
|
return new String(response.getBody()); |
||||||
|
} |
||||||
|
|
||||||
|
public String getPage(String term, String cookies) throws IOException, ApiException { |
||||||
|
return getPage(term, cookies, null); |
||||||
|
} |
||||||
|
} |
@ -1,27 +1,32 @@ |
|||||||
package cn.linghang.mywust.core.service.undergraduate; |
package cn.linghang.mywust.core.service.undergraduate; |
||||||
|
|
||||||
import cn.linghang.mywust.core.exception.ApiException; |
import cn.linghang.mywust.core.exception.ApiException; |
||||||
import cn.linghang.mywust.core.exception.ParseException; |
|
||||||
import cn.linghang.mywust.core.parser.undergraduate.ExamInfoParser; |
|
||||||
import cn.linghang.mywust.core.request.undergrade.BkjxRequestFactory; |
import cn.linghang.mywust.core.request.undergrade.BkjxRequestFactory; |
||||||
import cn.linghang.mywust.model.global.ExamInfo; |
|
||||||
import cn.linghang.mywust.network.RequestClientOption; |
import cn.linghang.mywust.network.RequestClientOption; |
||||||
import cn.linghang.mywust.network.Requester; |
import cn.linghang.mywust.network.Requester; |
||||||
import cn.linghang.mywust.network.entitys.HttpRequest; |
import cn.linghang.mywust.network.entitys.HttpRequest; |
||||||
import cn.linghang.mywust.network.entitys.HttpResponse; |
import cn.linghang.mywust.network.entitys.HttpResponse; |
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
|
|
||||||
import java.io.IOException; |
import java.io.IOException; |
||||||
import java.util.List; |
import java.util.Map; |
||||||
|
|
||||||
public class ExamInfoApiService extends UndergraduateApiService { |
public class UndergradScoreApiService extends UndergradApiServiceBase { |
||||||
|
|
||||||
public ExamInfoApiService(Requester requester) { |
public UndergradScoreApiService(Requester requester) { |
||||||
super(requester); |
super(requester); |
||||||
} |
} |
||||||
|
|
||||||
public String getExamInfoPage(String cookies, RequestClientOption requestClientOption) throws IOException, ApiException { |
@Override |
||||||
|
public String getPage(String cookie, Map<String, String> params, RequestClientOption option) throws ApiException, IOException { |
||||||
|
return this.getPage(cookie, option); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public String getPage(String cookie, Map<String, String> params) throws ApiException, IOException { |
||||||
|
return this.getPage(cookie, params, null); |
||||||
|
} |
||||||
|
|
||||||
|
public String getPage(String cookies, RequestClientOption requestClientOption) throws IOException, ApiException { |
||||||
HttpRequest request = BkjxRequestFactory.examScoreInfoRequest(cookies, "", "", ""); |
HttpRequest request = BkjxRequestFactory.examScoreInfoRequest(cookies, "", "", ""); |
||||||
HttpResponse response = requester.post(request, requestClientOption); |
HttpResponse response = requester.post(request, requestClientOption); |
||||||
|
|
@ -0,0 +1,16 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<groupId>cn.linghang</groupId> |
||||||
|
<artifactId>mywust-model</artifactId> |
||||||
|
<version>0.0.1-fixed</version> |
||||||
|
<dependencies> |
||||||
|
<dependency> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
<version>1.18.22</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
</project> |
@ -0,0 +1,16 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<groupId>cn.linghang</groupId> |
||||||
|
<artifactId>mywust-network-httpclient</artifactId> |
||||||
|
<version>0.0.1-fixed</version> |
||||||
|
<dependencies> |
||||||
|
<dependency> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
<version>1.18.22</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
</project> |
@ -0,0 +1,40 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<groupId>cn.linghang</groupId> |
||||||
|
<artifactId>mywust-network-okhttp</artifactId> |
||||||
|
<version>0.0.1-fixed</version> |
||||||
|
<dependencies> |
||||||
|
<dependency> |
||||||
|
<groupId>com.squareup.okhttp3</groupId> |
||||||
|
<artifactId>okhttp</artifactId> |
||||||
|
<version>3.14.9</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.slf4j</groupId> |
||||||
|
<artifactId>slf4j-api</artifactId> |
||||||
|
<version>1.7.36</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>cn.linghang</groupId> |
||||||
|
<artifactId>mywust-network</artifactId> |
||||||
|
<version>0.0.1-fixed</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>cn.linghang</groupId> |
||||||
|
<artifactId>mywust-util</artifactId> |
||||||
|
<version>0.0.1-fixed</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
<version>1.18.22</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
</project> |
@ -0,0 +1,22 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<groupId>cn.linghang</groupId> |
||||||
|
<artifactId>mywust-network</artifactId> |
||||||
|
<version>0.0.1-fixed</version> |
||||||
|
<dependencies> |
||||||
|
<dependency> |
||||||
|
<groupId>cn.linghang</groupId> |
||||||
|
<artifactId>mywust-util</artifactId> |
||||||
|
<version>0.0.1-fixed</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
<version>1.18.22</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
</project> |
@ -1,27 +1,105 @@ |
|||||||
package cn.linghang.mywust.network; |
package cn.linghang.mywust.network; |
||||||
|
|
||||||
|
import lombok.Builder; |
||||||
import lombok.Data; |
import lombok.Data; |
||||||
|
|
||||||
@Data |
@Data |
||||||
public class RequestClientOption { |
public class RequestClientOption { |
||||||
private Proxy proxy; |
private Proxy proxy; |
||||||
private long timeout; |
private long timeout; |
||||||
private boolean fallowUrlRedirect = false; |
private boolean fallowUrlRedirect; |
||||||
|
|
||||||
|
private boolean ignoreSSLError; |
||||||
|
|
||||||
@Data |
@Data |
||||||
|
@Builder |
||||||
public static class Proxy { |
public static class Proxy { |
||||||
private String address; |
private String address; |
||||||
private int port; |
private int port; |
||||||
} |
} |
||||||
|
|
||||||
|
public RequestClientOption() { |
||||||
|
this.proxy = null; |
||||||
|
this.timeout = 5; |
||||||
|
this.fallowUrlRedirect = false; |
||||||
|
this.ignoreSSLError = true; |
||||||
|
} |
||||||
|
|
||||||
|
public RequestClientOption(Proxy proxy, long timeout, boolean fallowUrlRedirect, boolean ignoreSSLError) { |
||||||
|
this.proxy = proxy; |
||||||
|
this.timeout = timeout; |
||||||
|
this.fallowUrlRedirect = fallowUrlRedirect; |
||||||
|
this.ignoreSSLError = ignoreSSLError; |
||||||
|
} |
||||||
|
|
||||||
public static final RequestClientOption DEFAULT_OPTION = newDefaultOption(); |
public static final RequestClientOption DEFAULT_OPTION = newDefaultOption(); |
||||||
|
|
||||||
private static RequestClientOption newDefaultOption() { |
private static RequestClientOption newDefaultOption() { |
||||||
RequestClientOption option = new RequestClientOption(); |
return new ConstantRequestClientOption(); |
||||||
option.setTimeout(5); |
} |
||||||
option.setProxy(null); |
|
||||||
option.setFallowUrlRedirect(false); |
/** |
||||||
|
* 常量化的RequestClientOption,对其使用setter时不会起任何作用 |
||||||
|
*/ |
||||||
|
public static class ConstantRequestClientOption extends RequestClientOption { |
||||||
|
@Override |
||||||
|
public Proxy getProxy() { |
||||||
|
return super.getProxy(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public long getTimeout() { |
||||||
|
return super.getTimeout(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isFallowUrlRedirect() { |
||||||
|
return super.isFallowUrlRedirect(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setProxy(Proxy proxy) {} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setTimeout(long timeout) {} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void setFallowUrlRedirect(boolean fallowUrlRedirect) {} |
||||||
|
} |
||||||
|
|
||||||
|
public static RequestClientOptionBuilder builder() { |
||||||
|
return new RequestClientOptionBuilder(); |
||||||
|
} |
||||||
|
|
||||||
|
public static final class RequestClientOptionBuilder { |
||||||
|
private final RequestClientOption requestClientOption; |
||||||
|
|
||||||
|
private RequestClientOptionBuilder() { |
||||||
|
requestClientOption = new RequestClientOption(); |
||||||
|
} |
||||||
|
|
||||||
|
public RequestClientOptionBuilder proxy(Proxy proxy) { |
||||||
|
requestClientOption.setProxy(proxy); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public RequestClientOptionBuilder timeout(long timeout) { |
||||||
|
requestClientOption.setTimeout(timeout); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public RequestClientOptionBuilder fallowUrlRedirect(boolean fallowUrlRedirect) { |
||||||
|
requestClientOption.setFallowUrlRedirect(fallowUrlRedirect); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
|
public RequestClientOptionBuilder ignoreSSLError(boolean ignoreSSLError) { |
||||||
|
requestClientOption.setIgnoreSSLError(ignoreSSLError); |
||||||
|
return this; |
||||||
|
} |
||||||
|
|
||||||
return option; |
public RequestClientOption build() { |
||||||
|
return requestClientOption; |
||||||
|
} |
||||||
} |
} |
||||||
} |
} |
||||||
|
@ -0,0 +1,12 @@ |
|||||||
|
import cn.linghang.mywust.core.exception.ParseException; |
||||||
|
import cn.linghang.mywust.core.parser.undergraduate.ExamInfoParser; |
||||||
|
import org.jsoup.Jsoup; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
|
||||||
|
public class ParseTest { |
||||||
|
public static void main(String[] args) throws IOException, ParseException { |
||||||
|
ExamInfoParser parser = new ExamInfoParser(); |
||||||
|
System.out.println(parser.parse(Jsoup.connect("http://127.0.0.1/a.html").get().toString())); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
<groupId>cn.linghang</groupId> |
||||||
|
<artifactId>mywust-util</artifactId> |
||||||
|
<version>0.0.1-fixed</version> |
||||||
|
<dependencies> |
||||||
|
<dependency> |
||||||
|
<groupId>commons-codec</groupId> |
||||||
|
<artifactId>commons-codec</artifactId> |
||||||
|
<version>1.15</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>com.google.guava</groupId> |
||||||
|
<artifactId>guava</artifactId> |
||||||
|
<version>31.1-jre</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
<dependency> |
||||||
|
<groupId>org.projectlombok</groupId> |
||||||
|
<artifactId>lombok</artifactId> |
||||||
|
<version>1.18.22</version> |
||||||
|
<scope>compile</scope> |
||||||
|
</dependency> |
||||||
|
</dependencies> |
||||||
|
</project> |
Loading…
Reference in new issue