ScoreJob.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Configuration;
  4. using System.Diagnostics;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Text.RegularExpressions;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. using FCS.Common;
  11. using FCS.Interface;
  12. using FCS.Models;
  13. using FCS.Models.DTO;
  14. using HtmlAgilityPack;
  15. using Quartz;
  16. namespace FCS.Crawler.ZCLotteryScore
  17. {/// <summary>
  18. /// 创 建:czx
  19. /// 日 期:2018-09-27
  20. /// 描 述:比分数据更新、获取
  21. /// </summary>
  22. public class ScoreJob : CommonJob
  23. {
  24. #region 全局变量定义
  25. private List<DataItemDetail> scoreTypeList;//类别枚举类型
  26. private List<DataItemDetail> scoreStatusList;//状态枚举类型
  27. private Dictionary<string, string> scoreStatusDict;//状态枚举类型-字典
  28. private List<ScoreJobDTO> scoreJobList;//页面爬取参数
  29. private List<F_Events> eventsList;//赛事信息
  30. private List<F_Team> teamList;//球队信息
  31. private List<F_Games> gameList;//球队信息
  32. private string starting = "2";//开始中
  33. private string sfcCode = "300";//足彩
  34. private List<F_Score> result = new List<F_Score>();
  35. #endregion
  36. public ScoreJob()
  37. {
  38. scoreTypeList = services.GetDataItem(DataItemDetailEnum.FootScoreType);
  39. scoreStatusList = services.GetDataItem(DataItemDetailEnum.FootScoreStatus);
  40. eventsList = services.Query<F_Events>().ToList();
  41. teamList = services.Query<F_Team>().ToList();
  42. gameList = services.Query<F_Games>(" AND Datename(year,StartDateTime)={0}".FormatMe(DateTime.Now.Year)).ToList();
  43. scoreStatusDict = new Dictionary<string, string>
  44. {
  45. {"未","1" },
  46. {"完","3" },
  47. {"推迟 ","4" }
  48. };
  49. scoreJobList = new List<ScoreJobDTO>{
  50. new ScoreJobDTO{
  51. Type="2",
  52. Code="201",
  53. SessionName="date",
  54. Ajax="true",
  55. Url="http://live.zgzcw.com/jz/"
  56. },//竞彩
  57. new ScoreJobDTO{
  58. Type="3",
  59. Code="300",
  60. SessionName ="issue",
  61. Ajax="true",
  62. Url="http://live.zgzcw.com/sfc/"
  63. },//足彩
  64. new ScoreJobDTO{
  65. Type="4",
  66. Code="400",
  67. SessionName ="issue",
  68. Ajax="true",
  69. Url="http://live.zgzcw.com/bd/"
  70. },//北单
  71. };
  72. }
  73. /// <summary>
  74. /// 更新
  75. /// </summary>
  76. public void Click()
  77. {
  78. scoreJobList.ForEach(p =>
  79. {
  80. result = new List<F_Score>();
  81. var scoreType = scoreTypeList.Where(s => s.ItemValue == p.Type).ToList()[0].Id;
  82. //期数数据
  83. var sessionList = GetSession(p.Url, scoreType, true).ToList();
  84. threadCount = sessionList.Count;
  85. finishcount = 0;
  86. sessionList.ForEach(q =>
  87. {
  88. Analysis(p, q, scoreType);
  89. });
  90. lock (locker)
  91. {
  92. while (finishcount != threadCount)
  93. {
  94. Thread.Sleep(5000);
  95. Monitor.Wait(locker);//等待
  96. }
  97. }
  98. var deleteWhere = "";
  99. sessionList.ForEach(d =>
  100. {
  101. deleteWhere += d.Replace("-", "") + ",";
  102. });
  103. deleteWhere = deleteWhere.ToString().Substring(0, deleteWhere.ToString().Length - 1);
  104. services.Delete<F_Score>("AND ScoreType='{0}' AND Session in ({1})".FormatMe(scoreType, deleteWhere));
  105. services.SqlBulkCopyAdd(result);
  106. });
  107. }
  108. /// <summary>
  109. /// 获取全部
  110. /// </summary>
  111. /// <param name="url"></param>
  112. public void GetALL(string url = "http://live.zgzcw.com/ls/AllData.action")
  113. {
  114. var result = new List<F_Score>();
  115. scoreJobList.ForEach(p =>
  116. {
  117. Task.Run(() =>
  118. {
  119. //期数数据
  120. var sessionList = GetSession(p.Url).ToList();
  121. sessionList.ForEach(q =>
  122. {
  123. Analysis(p, q);
  124. });
  125. });
  126. });
  127. while (true)
  128. {
  129. if (CommonHelper.ThreadsFinsh())
  130. break;
  131. }
  132. services.SqlBulkCopyAdd<F_Score>(result);
  133. }
  134. /// <summary>
  135. /// 数据分析
  136. /// </summary>
  137. /// <param name="p">比分</param>
  138. /// <param name="q">期数</param>
  139. /// <param name="type">比分类型</param>
  140. /// <returns></returns>
  141. private async Task Analysis(ScoreJobDTO p, string q, string type = "")
  142. {
  143. string url = "http://live.zgzcw.com/ls/AllData.action";
  144. await Task.Run(() =>
  145. {
  146. try
  147. {
  148. var dict = new Dictionary<string, string> {{ "code",p.Code},{ p.SessionName,q},{ "ajax",p.Ajax}};//formData参数拼接
  149. var doc = CommonHelper.GetHtmlHtmlDocument(new HtmlParameterDTO { Url = url, FormData = dict, Title = "matchid", Method = "POST" });
  150. var tr = doc.DocumentNode.SelectNodes(".//tr");
  151. while (tr == null && doc.DocumentNode.InnerHtml != ConfigurationManager.AppSettings["Termination"])
  152. {
  153. doc = doc = CommonHelper.GetHtmlHtmlDocument(new HtmlParameterDTO { Url = url, FormData = dict, Title = "matchid", Method = "POST" });
  154. tr = doc.DocumentNode.SelectNodes(".//tr");
  155. }
  156. if (doc.DocumentNode.InnerHtml == ConfigurationManager.AppSettings["Termination"])//不存在退出
  157. return;
  158. foreach (HtmlNode item in tr)
  159. {
  160. var td = item.SelectNodes(".//td");
  161. if (td == null)
  162. continue;
  163. if (td.Count < 5)
  164. break;
  165. string _result = "", status = "", halfResultatus = "", colourFruit = "", gameId = "";
  166. if (scoreStatusDict.ContainsKey(td[4].InnerText.Trim()))
  167. {
  168. status = scoreStatusList.Where(a => a.ItemValue.Contains(scoreStatusDict[td[4].InnerText.Trim()])).ToList()[0].Id;
  169. _result = td[6].SelectNodes(".//span")[0].InnerHtml.Replace("&nbsp;", "");
  170. halfResultatus = td[8].SelectNodes(".//span")[0].InnerHtml.Replace("&nbsp;", "");
  171. }
  172. else
  173. status = scoreStatusList.Where(a => a.ItemValue.Contains(starting)).ToList()[0].Id;
  174. if (p.Code == sfcCode)
  175. colourFruit = td[9].SelectNodes(".//strong") != null ? td[9].SelectNodes(".//strong")[0].InnerText : string.Empty;
  176. var compensate = tr[tr.IndexOf(item)].SelectSingleNode(".//div[@class='oupei']").SelectNodes("span");
  177. var asianDish = tr[tr.IndexOf(item)].SelectSingleNode(".//div[@class='yapan']").SelectNodes("span");
  178. var model = new F_Score
  179. {
  180. Id = CommonHelper.GetGuid().ToString(),
  181. EventId = eventsList.Where(s => s.Name.Contains(td[1].InnerText)).ToList().Count > 0 ? eventsList.Where(s => s.Name.Contains(td[1].InnerText)).ToList()[0].Id : "",
  182. GroupName = td[2].InnerText,
  183. StartDateTime = DateTime.Parse(td[3].Attributes["date"].Value),
  184. HomeTeamId = (from a in teamList
  185. where a.Name == Regex.Replace(td[5].SelectNodes(".//a")[0].InnerText, @"\s", "")
  186. select a.Id).Take(1).ToJoin(),
  187. VisitingTeamId = (from a in teamList
  188. where a.Name == Regex.Replace(td[7].SelectNodes(".//a")[0].InnerText, @"\s", "")
  189. select a.Id).Take(1).ToJoin(),
  190. HomeTeamName = td[5].SelectNodes(".//a")[0].InnerText,
  191. VisitingTeamName = td[7].SelectNodes(".//a")[0].InnerText,
  192. Status = status,
  193. EventName = td[1].SelectNodes(".//span")[0].InnerText,
  194. Result = _result.Trim() == "-" ? string.Empty : _result.Trim(),
  195. HalfResult = halfResultatus.Trim() == "-" ? string.Empty : halfResultatus.Trim(),
  196. ColourFruit = colourFruit,
  197. Session = int.Parse(q.Replace("-", "")),
  198. Compensate_SOdd = float.Parse(compensate == null ? "0" : compensate[0].InnerText),
  199. Compensate_POdd = float.Parse(compensate == null ? "0" : compensate[1].InnerText),
  200. Compensate_FOdd = float.Parse(compensate == null ? "0" : compensate[2].InnerText),
  201. AsianDish_SOdd = float.Parse(asianDish == null ? "0" : asianDish[0].InnerText),
  202. AsianDish_Disc = asianDish != null ? asianDish[1].InnerText : string.Empty,
  203. AsianDish_FOdd = float.Parse(asianDish == null ? "0" : asianDish[2].InnerText),
  204. CreateDateTime = DateTime.Now,
  205. ScoreType = type.IsEmpty() ? scoreTypeList.Where(s => s.ItemValue == p.Type).ToList()[0].Id : type,
  206. Sort = tr.IndexOf(item) + 1
  207. };
  208. model.GameId = (from a in gameList
  209. where a.HomeTeamId == model.HomeTeamId && a.VisitingTeamId == model.VisitingTeamId && ((DateTime)a.StartDateTime).ToString("yyyy-MM-dd") == model.StartDateTime.ToString("yyyy-MM-dd")
  210. select a.Id).Take(1).ToJoin();
  211. result.Add(model);
  212. }
  213. }
  214. catch (Exception ex)
  215. {
  216. }
  217. finally
  218. {
  219. lock (locker)
  220. {
  221. finishcount++;
  222. Monitor.Pulse(locker); //完成,通知等待队列,告知已完,执行下一个。
  223. }
  224. }
  225. });
  226. }
  227. /// <summary>
  228. /// 获取期数
  229. /// </summary>
  230. /// <param name="url"></param>
  231. /// <param name="type"></param>
  232. /// <param name="isUpdate"></param>
  233. /// <returns></returns>
  234. private IEnumerable<string> GetSession(string url, string type = "", bool isUpdate = false)
  235. {
  236. var list = new List<string>();
  237. var sessionList = new List<string>();
  238. if (isUpdate)
  239. {
  240. var nosessionList = services.Query<F_Score>(" AND (Result IS NULL OR Result ='') AND ScoreType='{0}'".FormatMe(type), "", "a.Session").ToList();
  241. if (nosessionList.Count <= 0)
  242. {
  243. nosessionList = services.Query<F_Score>(" AND ScoreType='{0}'".FormatMe(type), "", "max(a.Session) as Session").ToList();
  244. if (nosessionList.Count > 0)
  245. sessionList = (from a in nosessionList
  246. select a.Session.ToString()).Distinct().ToList();
  247. }
  248. else
  249. {
  250. sessionList = (from a in nosessionList
  251. select a.Session.ToString()).Distinct().ToList();
  252. }
  253. }
  254. var doc = CommonHelper.GetHtmlHtmlDocument(new HtmlParameterDTO { Url = url, Title = "足彩" ,Timeout=10000});
  255. var opent = doc.DocumentNode.SelectSingleNode(".//select[@id='matchSel']").SelectNodes(".//option");
  256. foreach (var item in opent)
  257. {
  258. list.Add(item.Attributes["value"].Value);
  259. }
  260. if (sessionList.Count > 0)
  261. {
  262. var list_y = from a in list
  263. join b in sessionList on a.Replace("-", "") equals b
  264. select b;
  265. if (list_y.Count() <= 0)
  266. list_y = sessionList;
  267. var session = list_y.OrderBy(p => p).ToList()[0];
  268. return (from a in list
  269. where int.Parse(a.Replace("-", "")) >= int.Parse(session)
  270. select a
  271. ).Distinct().ToList();
  272. }
  273. return list;
  274. }
  275. }
  276. }