index.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. const puppeteer = require('puppeteer');
  2. const fs = require('fs');
  3. let info;
  4. try {
  5. info = require('./config')();
  6. } catch (e) {
  7. try {
  8. info = require('./config.example')();
  9. } catch (e) {
  10. console.log("配置文件错误");
  11. process.exit();
  12. return;
  13. }
  14. }
  15. if (!info || !info[0] || !info[0][0] || !info[0][1] || info[0][0] === 'reply_info' || info[0][1] === 'sign') {
  16. console.log("配置文件错误");
  17. process.exit();
  18. return;
  19. }
  20. let infoOK = [];
  21. function fillZero(num) {
  22. return (num < 10) ? "0" + num : "" + num;
  23. }
  24. function getDate() {
  25. const now = new Date();
  26. return now.getFullYear() + "-" + fillZero(now.getMonth() + 1) + "-" + fillZero(now.getDate());
  27. }
  28. function getFullTime() {
  29. const now = new Date();
  30. const year = now.getFullYear(), month = now.getMonth() + 1, day = now.getDate(), hour = now.getHours(),
  31. min = now.getMinutes(), sec = now.getSeconds();
  32. return year + "-" + fillZero(month) + "-" + fillZero(day) + " " + fillZero(hour) + ":" + fillZero(min) + ":" +
  33. fillZero(sec);
  34. }
  35. async function interval() {
  36. const browser = await puppeteer.launch({
  37. // headless: false, // 是否隐藏窗口(默认true)
  38. // defaultViewport: {width: 800, height: 600} // 截图大小
  39. });
  40. let lastDay = null; // 记录上一秒的日期
  41. setInterval(async function () {
  42. const now = new Date();
  43. const day = now.getDate();
  44. const hour = now.getHours();
  45. const min = now.getMinutes();
  46. const sec = now.getSeconds();
  47. if (lastDay !== null && lastDay !== day) {
  48. // 日期变动,清空数组
  49. infoOK = [];
  50. }
  51. lastDay = day;
  52. if ((hour === 0 && min < 30) || (hour === 0 && min === 15 && sec <= 10) || hour >= 16) {
  53. return;
  54. }
  55. for (let i = 0, j = info.length; i < j; i++) {
  56. if (info[i] && info[i][0] && info[i][1] && !infoOK[i]) {
  57. infoOK[i] = true;
  58. try {
  59. await run(browser, info[i][0], info[i][1]);
  60. } catch (e) {
  61. console.log("[ " + getFullTime() + " ]", i, e);
  62. setTimeout(function () {
  63. infoOK[i] = false; // 出错,一分钟后重试
  64. }, 60000);
  65. // return;
  66. }
  67. }
  68. }
  69. }, 1000);
  70. }
  71. function sleep(time) {
  72. return new Promise(function (resolve) {
  73. setTimeout(function () {
  74. resolve();
  75. }, time);
  76. });
  77. }
  78. async function run(browser, replyInfo, sign) {
  79. return new Promise(async function (resolve, reject) {
  80. const page = await browser.newPage();
  81. try {
  82. await page.goto("https://testmis.ssti.net.cn/xswxcs/?reply_info=" + replyInfo + "&sign=" + sign);
  83. } catch (e) {
  84. await page.close();
  85. reject(e);
  86. return;
  87. }
  88. if (page.url().indexOf("https://open.weixin.qq.com/") !== -1) {
  89. await page.close();
  90. reject("URL Error");
  91. return;
  92. }
  93. try {
  94. await page.goto("https://testmis.ssti.net.cn/xswxcs/pages/Epidemic/EpidemicApply.aspx", {waitUntil: 'networkidle2'});
  95. } catch (e) {
  96. await page.close();
  97. reject(e);
  98. return;
  99. }
  100. if (page.url().indexOf("https://open.weixin.qq.com/") !== -1) {
  101. await page.close();
  102. reject("URL Error");
  103. return;
  104. }
  105. try {
  106. const msg = await page.$eval("#layui-m-layer0 .layui-m-layercont", el => el.innerText);
  107. if (msg.indexOf("每日开放时间为") !== -1) {
  108. await page.close();
  109. reject("Time Error");
  110. return;
  111. }
  112. } catch (e) {
  113. // 捕捉可能的eval错误
  114. }
  115. let name;
  116. try {
  117. name = await page.$eval("#div2 input", el => el.value);
  118. } catch (e) {
  119. await page.close();
  120. reject("Get Name Error");
  121. return;
  122. }
  123. await page.on('response', async (response) => {
  124. if (response.url() === "https://testmis.ssti.net.cn/xswxcs/Api/MedicalObHandle.ashx?action=add") {
  125. const data = await response.json();
  126. if (data["msg"].indexOf("成功") !== -1) {
  127. console.log("[ " + getFullTime() + " ]" + name + " 成功");
  128. try {
  129. await page.screenshot({path: "img/" + name + "-" + getDate() + '.png'});
  130. } catch (e) {
  131. // 捕捉可能的截图错误
  132. }
  133. // await sleep(2000);
  134. await page.close();
  135. resolve();
  136. } else {
  137. console.log(name + " 失败:" + data["msg"]);
  138. await page.close();
  139. reject(data["msg"]);
  140. }
  141. } else {
  142. // 不应该还有其他请求(也可能是提交URL发生改变)
  143. await page.close();
  144. reject("Unknown URL: " + response.url());
  145. }
  146. });
  147. try {
  148. await page.click("#Apply_Epidemic");
  149. } catch (e) {
  150. await page.close();
  151. reject("Submit Error");
  152. }
  153. // await sleep(2000);
  154. // await page.close();
  155. // resolve();
  156. });
  157. }
  158. // 新建文件夹
  159. function mkdir() {
  160. return new Promise(function (resolve, reject) {
  161. fs.mkdir("./img", (err) => {
  162. if (err && err.code !== 'EEXIST') {
  163. reject(err);
  164. } else {
  165. resolve();
  166. }
  167. });
  168. });
  169. }
  170. // 初始化
  171. async function init() {
  172. await mkdir();
  173. interval();
  174. }
  175. init();