前言
足球发展已经超百余年,但发现市面上没有真正比较好的预测分析软件,本着十几年的JAVA开发经验,想着亲手做一个关于足球走地大小球、让
一、选择稳定的网站足球网站数据采集数据
做此工具,我选择的是球琛网的走地数据,主要采集“即时比分”相关列表数据,及亚欧大相关初盘、终盘、滚球相关赔率。
球、角球的分析软件看看情况是怎么样的。
编辑
软件采集的代码片段如下://从网页取得数据 InputStream in =null; try{ JavaScriptPage jspage = (JavaScriptPage) HtmlunitHelper.getPage(url, requestHead); in=jspage.getWebResponse().getContentAsStream(); jspage.getEnclosingWindow().getWebClient().closeAllWindows(); }catch(Exception e){ HtmlPage jspage = (HtmlPage) HtmlunitHelper.getPage(url, requestHead); in=jspage.getWebResponse().getContentAsStream(); jspage.getEnclosingWindow().getWebClient().closeAllWindows(); } InputStreamReader inr = new InputStreamReader(in, "UTF-8"); BufferedReader br = new BufferedReader(inr); String s = null; //String site="live"; while((s=br.readLine())!=null){ if(pattern.matcher(s).find()){ listStr.add(s); } }for(String s:listStr) { Match match = new Match(); String strData = s.split("\"", s.lastIndexOf("\""))[1]; String[] data = StringUtil.split(strData,"\\^"); try{ match.setJqqc(data[48]+"-"+data[49]); }catch(Exception e){} match.setId(data[0]); match.setGameName(data[2]); match.setGameFirstName(data[2].substring(0,1)); match.setGameNameC(data[3]); match.setTeams1(data[5].replace("<font color=#880000>", "").replace("</font>", "")); match.setTeams1C(data[6].replace("<font color=#880000>", "").replace("</font>", "")); match.setTeams2(data[8].replace("<font color=#880000>", "").replace("</font>", "")); match.setTeams2C(data[9].replace("<font color=#880000>", "").replace("</font>", "")); match.setScore(data[14]+"-"+data[15]); match.setYellowCard1(Integer.parseInt(data[20])); match.setYellowCard2(Integer.parseInt(data[21])); match.setRedCard1(Integer.parseInt(data[18])); String team1=match.getTeams1(); String team2=match.getTeams2(); try{ team1 = (String)engine.eval("T[\""+data[37]+"_3\"][0]"); team2 = (String)engine.eval("T[\""+data[38]+"_3\"][0]"); team1 = team1.replaceAll(" ", ""); team2 = team2.replaceAll(" ", ""); }catch(Exception e){} try{ match.setRedCard2(Integer.parseInt(data[19])); }catch(Exception e){} team1=team1.replace("U19", ""); team1=team1.replace("U20", ""); team1=team1.replace("U21", ""); team1=team1.replace("U22", ""); team1=team1.replace("U23", ""); team1=team1.replace("B队", ""); team1=team1.replace("(中)", ""); team2=team2.replace("U19", ""); team2=team2.replace("U20", ""); team2=team2.replace("U21", ""); team2=team2.replace("U22", ""); team2=team2.replace("U23", ""); team2=team2.replace("B队", ""); team2=team2.replace("(中)", ""); match.setTeamHg1(team1); match.setTeamHg2(team2); match.setHalfCourt(data[16]+"-"+data[17]); if("-".equals(match.getHalfCourt())){ match.setHalfCourt(match.getScore()); } String[] t = data[12].split(","); int statas = Integer.parseInt(data[13]); Date date = new Date(Integer.parseInt(t[0])-1900,Integer.parseInt(t[1]),Integer.parseInt(t[2]),Integer.parseInt(t[3]),Integer.parseInt(t[4]),Integer.parseInt(t[5])); long gotime = (System.currentTimeMillis() - date.getTime())/(1000*60); String strGotime = ""; try{ if(statas==1){ strGotime = gotime+""; if(gotime>45) strGotime = "45+"; }else if(statas==3){ strGotime = gotime+46+""; if(gotime+46>90) strGotime = "90+"; }else{ strGotime = state_ch[statas+14]; } }catch(Exception e){ //e.printStackTrace(); strGotime=""; log.info("007获取状态出错,team1:"+match.getTeams1()+",statas:"+statas+",gotime:"+gotime+",error:"+e.getMessage()); } match.setStatus(strGotime); // if(match.getStatus()==null||"".equals(match.getStatus())||"推迟".equals(match.getStatus())||"待定".equals(match.getStatus())){// if(!"true".equals(wkbsMap.get("wkbs"))){// continue;// }// } /*if("莫斯科斯巴达".equals(team1)||"清水心跳".equals(team1)||"托利马".equals(team1)){ log.info("比赛状态========>>"+strGotime+",team1==>>"+team1); }*/ //log.info("角球比分:"+match.getJqqc()+"==>>"+match.getTeamHg1()+" VS "+match.getTeamHg2()); //String strdataTime = t[0]+"-"+t[1]+"-"+t[2]+" "+data[11];// 2018,3,10,20,15,00 //log.info("data[12].trim()===>>"+data[12].trim()) match.setDataTime(DateUtils.parseDate(data[12].trim(), "yyyy,MM,dd,HH,mm,ss")); Calendar dateTime = Calendar.getInstance(); dateTime.setTime(match.getDataTime()); dateTime.add(Calendar.MONTH, 1); match.setDataTime(dateTime.getTime()); // Date dataTime = new Date(Integer.parseInt(t[0])-1900,Integer.parseInt(t[1]),Integer.parseInt(t[2]),Integer.parseInt(data[11].split(":")[0]),Integer.parseInt(data[11].split(":")[1]),0);// match.setDataTime(dataTime); String runMath="0"; try{ if(data[28].equals("True")){ String[] data1 = ch_goin.get(match.getId()); if(data1!=null){ if(data1[5].equals("2")) runMath ="2"; }else{ runMath ="1"; } }else{ runMath ="0"; } }catch(Exception e){ log.error("获取runMath异常"); } String[] goindata = goin.get(match.getId()); Double exponential = null; Double sbExponentiald = null; String sb = ""; if(goindata!=null){ if(goindata[14].equals("0")){ try { exponential = Double.parseDouble(goindata[3]); sbExponentiald = Double.parseDouble(goindata[4]); sb = this.Goal2GoalCn(goindata[2]); }catch(Exception e) { log.error("获取SB异常,"+team1+" VS "+team2+",goindata[3]:"+goindata[3]); } }else{ exponential = null; sbExponentiald = null; sb = "封"; } } match.setRunMath(runMath);
采集还是相对简单,主要是读取球琛的JSON数组,前端
但单是赔率数据是不够的,因此我们还采集了球琛的技术统计数据,如危险进攻数、射门数、射正射门数、传球成功率、控球率、进攻等,后面实现策略逻辑时,需要从这些数据中去查找规律。
二、开发筛选策略平台,动态设置筛选参数逻辑
这一步主要设置自己的动态策略,条件组合,参数调配等,下面简单列举其中一个策略,如:
70分钟前,主队让球,
控球率主队大于客队
危险进攻数主队大于客队12个以上
进攻主队大于客队20个
射门数主队大于客队
射正射门数主队大于客队
让球盘小于2
主队比分大于或等于客队比分
主队进攻大于 50
符合此所有条件后,看好主队获胜。
因此需要开发一些常用的界面,我们的界面如下,在这里就需要有一点点SQL的经验了:
是通过开源的UI展示出来,界面如下:
三、定时任务执行,根据筛选策略生成相关符合策略的明细记录
策略写好后,就来到了这一步,这一步主要是配置系统的定任务,让定任务去执行条件策略的频繁筛选,
四、比赛完成后需要对生成的明细记录进行结算,统计每条策略的胜率情况
这是最后一步,就是对生成的预测条件进行胜率统计,下面展示一下我们的比赛结果结算方法代码及界面效果:
代码:
总结
该软件适合初盘、滚球的大小球、让球、角球的相关分析,非常灵活,这些实践付出了不少,但也收获了很多,从陌生到熟悉,到最后慢慢深入,所以任何领域都需要我们认真学习,想干就干,敢于实践,才会做到你想做的东西。