VacationFutureCallback.java 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package com.goafanti.crawler.callback;
  2. import java.util.ArrayList;
  3. import java.util.Calendar;
  4. import java.util.HashSet;
  5. import java.util.List;
  6. import java.util.Map;
  7. import java.util.Set;
  8. import java.util.regex.Matcher;
  9. import java.util.regex.Pattern;
  10. import com.alibaba.fastjson.JSON;
  11. public class VacationFutureCallback extends CrawlerFutureCallback {
  12. private String year = null;
  13. private Pattern dateTime = null;
  14. private Pattern dateTimePeriod = null;
  15. private Pattern dateTimePeriod2 = null;
  16. private Set<String> vacations = null;
  17. private Set<String> workDays = null;
  18. public VacationFutureCallback(Map<String, String> result) {
  19. setResult(result);
  20. }
  21. @Override
  22. protected void handleWebpage(String pageContent) {
  23. Pattern pattern = Pattern.compile("<td class=\"b12c\">([\\s\\S]*?)</td>", Pattern.MULTILINE);
  24. Matcher m = pattern.matcher(pageContent);
  25. if (m.find()) {
  26. handleNotice(m.group(1));
  27. }
  28. }
  29. private void handleNotice(String notice) {
  30. Matcher yearMatcher = Pattern.compile("关于(\\d+)年").matcher(notice);
  31. if (yearMatcher.find()) {
  32. year = yearMatcher.group(1);
  33. } else {
  34. return;
  35. }
  36. List<String> parts = new ArrayList<>();
  37. Matcher linesMatcher = Pattern.compile("<p.*?>([\\s\\S]+?)</p>", Pattern.MULTILINE).matcher(notice);
  38. while (linesMatcher.find()) {
  39. parts.add(linesMatcher.group(1));
  40. }
  41. handleParts(parts);
  42. }
  43. private void handleParts(List<String> parts) {
  44. dateTime = Pattern.compile("(\\d+)月(\\d+)日");
  45. dateTimePeriod = Pattern.compile("(\\d+)月(\\d+)日至(\\d+)日");
  46. dateTimePeriod2 = Pattern.compile("(\\d+)月(\\d+)日至(\\d+)月(\\d+)日");
  47. vacations = new HashSet<>();
  48. workDays = new HashSet<>();
  49. for (String part : parts) {
  50. for (String s : part.split("<.*?>")) {
  51. if (s.matches("\\d+月\\d+日.*")) {
  52. handleLine(s);
  53. }
  54. }
  55. }
  56. Calendar c = Calendar.getInstance();
  57. int y = Integer.parseInt(year);
  58. c.set(y, 0, 1);
  59. while (c.get(Calendar.YEAR) == y) {
  60. int dow = c.get(Calendar.DAY_OF_WEEK);
  61. if (dow == 7 || dow == 1) {
  62. String ckey = getDateStr(c);
  63. if (!workDays.contains(ckey)) {
  64. vacations.add(ckey);
  65. }
  66. }
  67. c.add(Calendar.DATE, 1);
  68. }
  69. if (this.getResult() != null) {
  70. this.getResult().put(year, JSON.toJSONString(vacations));
  71. }
  72. }
  73. private void handleLine(String line) {
  74. for (String s : line.split("。")) {
  75. boolean isVacation = s.indexOf("上班") == -1;
  76. if (findNoPeriod2(s, isVacation) && findNoPeriod(s, isVacation)) {
  77. Matcher dtm = dateTime.matcher(s);
  78. while (dtm.find()) {
  79. if (isVacation) {
  80. vacations.add(getDateStr(Integer.parseInt(dtm.group(1)), Integer.parseInt(dtm.group(2))));
  81. } else {
  82. workDays.add(getDateStr(Integer.parseInt(dtm.group(1)), Integer.parseInt(dtm.group(2))));
  83. }
  84. }
  85. }
  86. }
  87. }
  88. private boolean findNoPeriod2(String s, boolean isVacation) {
  89. Matcher dtp2m = dateTimePeriod2.matcher(s);
  90. if (dtp2m.find()) {
  91. addPeriodToSet(dtp2m.group(1), dtp2m.group(2), dtp2m.group(3), dtp2m.group(4),
  92. isVacation ? vacations : workDays);
  93. return false;
  94. }
  95. return true;
  96. }
  97. private boolean findNoPeriod(String s, boolean isVacation) {
  98. Matcher dtp2m = dateTimePeriod.matcher(s);
  99. if (dtp2m.find()) {
  100. addPeriodToSet(dtp2m.group(1), dtp2m.group(2), dtp2m.group(1), dtp2m.group(3),
  101. isVacation ? vacations : workDays);
  102. return false;
  103. }
  104. return true;
  105. }
  106. private void addPeriodToSet(String stM, String stD, String edM, String edD, Set<String> set) {
  107. Calendar st = Calendar.getInstance();
  108. st.set(Integer.parseInt(year), Integer.parseInt(stM) - 1, Integer.parseInt(stD));
  109. Calendar ed = (Calendar) st.clone();
  110. ed.set(Integer.parseInt(year), Integer.parseInt(edM) - 1, Integer.parseInt(edD));
  111. while (ed.after(st)) {
  112. set.add(getDateStr(st));
  113. st.add(Calendar.DATE, 1);
  114. }
  115. set.add(getDateStr(ed));
  116. }
  117. private String getDateStr(Calendar c) {
  118. return getDateStr(c.get(Calendar.MONTH) + 1, c.get(Calendar.DATE));
  119. }
  120. private String getDateStr(int m, int d) {
  121. StringBuilder sb = new StringBuilder(year);
  122. if (m < 10) {
  123. sb.append(0);
  124. }
  125. sb.append(m);
  126. if (d < 10) {
  127. sb.append(0);
  128. }
  129. sb.append(d);
  130. return sb.toString();
  131. }
  132. }