HongKongSMHLHCJob.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using HtmlAgilityPack;
  6. using Quartz;
  7. using SCC.Common;
  8. using SCC.Crawler.Tools;
  9. using SCC.Interface;
  10. using SCC.Models;
  11. namespace SCC.Crawler.DT
  12. {
  13. /// <summary>
  14. /// 香港六合彩
  15. /// </summary>
  16. [DisallowConcurrentExecution]
  17. [PersistJobDataAfterExecution]
  18. public class HongKongSMHLHCJob : IJob
  19. {
  20. /// <summary>
  21. /// 初始化函数
  22. /// </summary>
  23. public HongKongSMHLHCJob()
  24. {
  25. log = new LogHelper();
  26. services = IOC.Resolve<IDTOpenCode>();
  27. email = IOC.Resolve<IEmail>();
  28. }
  29. /// <summary>
  30. /// 作业执行入口
  31. /// </summary>
  32. /// <param name="context">作业执行上下文</param>
  33. public void Execute(IJobExecutionContext context)
  34. {
  35. Config = CommonHelper.GetConfigFromDataMap(context.JobDetail.JobDataMap);
  36. //预设节假日不开奖
  37. if (Config.SkipDate.Contains(CommonHelper.SCCSysDateTime.ToString("yyyyMMdd"))) return;
  38. LatestItem = context.JobDetail.JobDataMap["LatestItem"] as OpenCode7DTModel;
  39. try
  40. {
  41. //服务启动时配置初始数据
  42. if (LatestItem == null)
  43. {
  44. LatestItem = services.GetOpenCode7DTLastItem(currentLottery);
  45. if (LatestItem == null)
  46. LatestItem = new OpenCode7DTModel
  47. {
  48. Term = CommonHelper.GenerateQiHaoYYYYQQQ(0),
  49. OpenTime = new DateTime(CommonHelper.SCCSysDateTime.Year, 1, 1)
  50. };
  51. }
  52. //程序时间第二天,程序根据配置检查是否昨天有开奖
  53. isGetData = false;
  54. if (CommonHelper.CheckDTIsNeedGetData(Config)) //
  55. DoMainUrl();
  56. DoBackUrl();
  57. if (!LatestItem.Term.ToString().StartsWith(CommonHelper.SCCSysDateTime.ToString("yy")))
  58. LatestItem = new OpenCode7DTModel
  59. {
  60. Term = CommonHelper.GenerateQiHaoYYYYQQQ(0),
  61. OpenTime = new DateTime(CommonHelper.SCCSysDateTime.Year, 1, 1)
  62. };
  63. //当今日开奖并且当前时间是晚上8点过后开始抓取
  64. if (CommonHelper.CheckTodayIsOpenDay(Config) && CommonHelper.SCCSysDateTime.Hour > 12) DoMainUrl();
  65. }
  66. catch (Exception ex)
  67. {
  68. log.Error(GetType(), string.Format("【{0}】抓取时发生错误,错误信息【{1}】", Config.Area + currentLottery, ex.Message));
  69. }
  70. //保存最新期号
  71. context.JobDetail.JobDataMap["LatestItem"] = LatestItem;
  72. }
  73. #region 通过备用站爬取数据
  74. private void DoBackUrl()
  75. {
  76. if (!string.IsNullOrEmpty(Config.BackUrl))
  77. {
  78. var openList = GetOpenListFromBackUrl(Config.BackUrl);
  79. if (openList.Count == 0) return; //无抓取数据
  80. //抓取到的最新期数
  81. var newestQiHao = Convert.ToInt32(openList.First().Term.ToString());
  82. //数据库里面最新期数
  83. var startQiNum = Convert.ToInt32(LatestItem.Term.ToString());
  84. if (startQiNum > newestQiHao) return; //无最新数据
  85. //处理最新开奖数据
  86. var getQiHao = string.Empty;
  87. OpenCode7DTModel matchItem = null;
  88. for (var i = startQiNum; i <= newestQiHao; i++)
  89. {
  90. getQiHao = i.ToString();
  91. matchItem = openList.FirstOrDefault(r => r.Term.ToString() == getQiHao);
  92. if (matchItem != null && services.AddDTOpen7Code(currentLottery, matchItem))
  93. {
  94. //Do Success Log
  95. log.Info(GetType(), CommonHelper.GetJobMainLogInfo(Config, getQiHao));
  96. LatestItem = matchItem;
  97. isGetData = true;
  98. }
  99. }
  100. }
  101. }
  102. /// <summary>
  103. /// 获取备用站点开奖列表数据
  104. /// </summary>
  105. /// <returns></returns>
  106. private List<OpenCode7DTModel> GetOpenListFromBackUrl(string BackUrl)
  107. {
  108. var result = new List<OpenCode7DTModel>();
  109. try
  110. {
  111. var url = new Uri(BackUrl);
  112. var htmlResource = NetHelper.GetUrlResponse(BackUrl, Encoding.GetEncoding("gb2312"));
  113. if (htmlResource == null) return result;
  114. var doc = new HtmlDocument();
  115. doc.LoadHtml(htmlResource);
  116. var table = doc.DocumentNode.SelectNodes("//table[@border='1']");
  117. if (table == null) return result;
  118. var trs = table[1].ChildNodes.Where(s => s.Name.ToLower() == "tr").ToList();
  119. OpenCode7DTModel model = null;
  120. var optimizeUrl = string.Empty;
  121. for (var i = 1; i < trs.Count; i++) //第一二行为表头
  122. {
  123. var tds = trs[i].ChildNodes.Where(node => node.Name == "td").ToList();
  124. if (tds.Count < 16) continue;
  125. model = new OpenCode7DTModel();
  126. model.OpenTime = Convert.ToDateTime(tds[1].InnerText);
  127. model.Term = Convert.ToInt64(TermSet(tds[2].InnerText));
  128. var openCodeString = tds[3].InnerText.Replace("shownumber(\"", "").Replace("\")", "").Trim().Split(','); ;
  129. model.OpenCode1 = Convert.ToInt32(openCodeString[0]);
  130. model.OpenCode2 = Convert.ToInt32(openCodeString[1]);
  131. model.OpenCode3 = Convert.ToInt32(openCodeString[2]);
  132. model.OpenCode4 = Convert.ToInt32(openCodeString[3]);
  133. model.OpenCode5 = Convert.ToInt32(openCodeString[4]);
  134. model.OpenCode6 = Convert.ToInt32(openCodeString[5]);
  135. model.OpenCode7 = Convert.ToInt32(tds[4].InnerText.Replace("shownumber(\"", "").Replace("\")", "").Trim());
  136. model.Spare = string.Empty;
  137. if (result.SingleOrDefault(w => w.Term == model.Term) == null) result.Add(model);
  138. }
  139. var checkDataHelper = new CheckDataHelper();
  140. var dbdata = services.GetListS<OpenCode7DTModel>(currentLottery)
  141. .ToDictionary(w => w.Term.ToString(), w => w.GetCodeStr());
  142. checkDataHelper.CheckData(dbdata, result.ToDictionary(w => w.Term.ToString(), w => w.GetCodeStr()),
  143. Config.Area, currentLottery);
  144. result = result.OrderByDescending(S => S.Term).ToList();
  145. }
  146. catch (Exception ex)
  147. {
  148. log.Error(GetType(),
  149. string.Format("【{0}】通过主站点抓取开奖列表时发生错误,错误信息【{1}】", Config.Area + currentLottery, ex.Message));
  150. }
  151. return result;
  152. }
  153. private String TermSet(string Term)
  154. {
  155. string date = CommonHelper.SCCSysDateTime.ToString("yyyy");
  156. string Qishu;
  157. if (Term.Length == 1) {
  158. Qishu = date + "00" + Term;
  159. }
  160. else if(Term.Length == 2)
  161. {
  162. Qishu = date + "0" + Term;
  163. }
  164. else
  165. {
  166. Qishu = date + Term;
  167. }
  168. return Qishu;
  169. }
  170. #endregion
  171. #region 通过主站爬取数据
  172. private void DoMainUrl()
  173. {
  174. if (!string.IsNullOrEmpty(Config.MainUrl))
  175. {
  176. var openList = GetOpenListFromMainUrl(Config.MainUrl);
  177. if (openList.Count == 0) return; //无抓取数据
  178. //抓取到的最新期数
  179. var newestQiHao = Convert.ToInt32(openList.First().Term.ToString());
  180. //数据库里面最新期数
  181. var startQiNum = Convert.ToInt32(LatestItem.Term.ToString());
  182. if (startQiNum > newestQiHao) return; //无最新数据
  183. //处理最新开奖数据
  184. var getQiHao = string.Empty;
  185. OpenCode7DTModel matchItem = null;
  186. for (var i = startQiNum; i <= newestQiHao; i++)
  187. {
  188. getQiHao = i.ToString();
  189. matchItem = openList.FirstOrDefault(r => r.Term.ToString() == getQiHao);
  190. if (matchItem != null && services.AddDTOpen7Code(currentLottery, matchItem))
  191. {
  192. //Do Success Log
  193. log.Info(GetType(), CommonHelper.GetJobMainLogInfo(Config, getQiHao));
  194. LatestItem = matchItem;
  195. isGetData = true;
  196. }
  197. }
  198. }
  199. }
  200. /// <summary>
  201. /// 获取备用站点开奖列表数据
  202. /// </summary>
  203. /// <returns></returns>
  204. private List<OpenCode7DTModel> GetOpenListFromMainUrl(string mainUrl)
  205. {
  206. var result = new List<OpenCode7DTModel>();
  207. try
  208. {
  209. var url = new Uri(mainUrl);
  210. var htmlResource = NetHelper.GetUrlResponse(mainUrl, Encoding.GetEncoding("UTF-8"));
  211. if (htmlResource == null) return result;
  212. var doc = new HtmlDocument();
  213. doc.LoadHtml(htmlResource);
  214. var div = doc.DocumentNode.SelectSingleNode("//div[@class='bd']");
  215. if (div == null) return result;
  216. var table = div.ChildNodes.Where(node => node.Name == "table").ToList();
  217. if (table == null) return result;
  218. var trs = table[0].ChildNodes.Where(node => node.Name == "tr").ToList();
  219. OpenCode7DTModel model = null;
  220. var optimizeUrl = string.Empty;
  221. for (var i = 1; i < trs.Count; i++) //第一二行为表头
  222. {
  223. var tds = trs[i].ChildNodes.Where(node => node.Name == "td").ToList();
  224. if (tds.Count < 23) continue;
  225. model = new OpenCode7DTModel();
  226. var QiHao = tds[0].InnerText.Substring(0, 4) + tds[1].InnerText.Trim().Substring(0, 3);
  227. model.Term = Convert.ToInt64(QiHao);
  228. model.OpenTime = Convert.ToDateTime(tds[0].InnerText);
  229. var openCodeString = tds[2].InnerText.Trim();
  230. model.OpenCode1 = Convert.ToInt32(openCodeString.Substring(0, 2));
  231. model.OpenCode2 = Convert.ToInt32(openCodeString.Substring(3, 2));
  232. model.OpenCode3 = Convert.ToInt32(openCodeString.Substring(6, 2));
  233. model.OpenCode4 = Convert.ToInt32(openCodeString.Substring(9, 2));
  234. model.OpenCode5 = Convert.ToInt32(openCodeString.Substring(12, 2));
  235. model.OpenCode6 = Convert.ToInt32(openCodeString.Substring(15, 2));
  236. model.OpenCode7 = Convert.ToInt32(tds[3].InnerText.Trim().Substring(0, 2));
  237. model.Spare = string.Empty;
  238. if (result.SingleOrDefault(w => w.Term == model.Term) == null) result.Add(model);
  239. }
  240. var checkDataHelper = new CheckDataHelper();
  241. var dbdata = services.GetListS<OpenCode7DTModel>(currentLottery)
  242. .ToDictionary(w => w.Term.ToString(), w => w.GetCodeStr());
  243. checkDataHelper.CheckData(dbdata, result.ToDictionary(w => w.Term.ToString(), w => w.GetCodeStr()),
  244. Config.Area, currentLottery);
  245. result = result.OrderByDescending(S => S.Term).ToList();
  246. }
  247. catch (Exception ex)
  248. {
  249. log.Error(GetType(),
  250. string.Format("【{0}】通过主站点抓取开奖列表时发生错误,错误信息【{1}】", Config.Area + currentLottery, ex.Message));
  251. }
  252. return result;
  253. }
  254. /// <summary>
  255. /// 完善备用站点江苏体彩7位数开奖实体信息
  256. /// </summary>
  257. /// <param name="model"></param>
  258. /// <summary>
  259. /// 配置信息
  260. /// </summary>
  261. private SCCConfig Config;
  262. /// <summary>
  263. /// 当天抓取的最新一期开奖记录
  264. /// </summary>
  265. private OpenCode7DTModel LatestItem;
  266. /// <summary>
  267. /// 当天抓取失败列表
  268. /// </summary>
  269. private List<string> FailedQiHaoList = null;
  270. /// <summary>
  271. /// 日志对象
  272. /// </summary>
  273. private readonly LogHelper log;
  274. /// <summary>
  275. /// 数据服务
  276. /// </summary>
  277. private readonly IDTOpenCode services;
  278. /// <summary>
  279. /// 当前彩种
  280. /// </summary>
  281. private SCCLottery currentLottery => SCCLottery.HongKongSMHLHC;
  282. /// <summary>
  283. /// 邮件接口
  284. /// </summary>
  285. private IEmail email;
  286. /// <summary>
  287. /// 是否本次运行抓取到开奖数据
  288. /// </summary>
  289. private bool isGetData;
  290. #endregion
  291. }
  292. }