新球体育网(球探)手机端网页,比赛的分析页面根据开盘时间列出各家公司,勾选所需公司后点击按钮生成表格,通过各家公司的让球走势分析赛果。
// ==UserScript==
// @name 新球体育网亚盘分析
// @namespace http://dol.freevar.com/
// @version 0.3
// @description 新球体育网(球探)手机端网页,比赛的分析页面根据开盘时间列出各家公司,勾选所需公司后点击按钮生成表格,通过各家公司的让球走势分析赛果。
// @author Dolphin
// @match https://m.titan007.com/Analy/Analysis/*
// @match https://m.titan007.com/analy/Analysis/*
// @run-at document-end
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 公司列表及对应的ID
const companies = [
{ companyId: 1, nameCn: "澳门" },
{ companyId: 8, nameCn: "Bet365" },
{ companyId: 12, nameCn: "易胜博" },
{ companyId: 14, nameCn: "伟德" },
{ companyId: 17, nameCn: "明陞" },
{ companyId: 23, nameCn: "金宝博" },
{ companyId: 24, nameCn: "12Bet" },
{ companyId: 31, nameCn: "利记" },
{ companyId: 35, nameCn: "盈禾" },
{ companyId: 42, nameCn: "18Bet" },
{ companyId: 47, nameCn: "平博" },
{ companyId: 48, nameCn: "香港" },
{ companyId: 9, nameCn: "威廉" },
{ companyId: 19, nameCn: "Inter" },
{ companyId: 50, nameCn: "1xBet" }
];
// 已选择的公司
let selectedComp = [];
// 格式化ModifyTime(yyyyMMddHHmmss)为日月时分
function formatModifyTime(timeStr) {
if (!timeStr || timeStr.length !== 14) return "";
const month = timeStr.substr(4, 2);
const day = timeStr.substr(6, 2);
const hour = timeStr.substr(8, 2);
const minute = timeStr.substr(10, 2);
return `${month}-${day} ${hour}:${minute}`;
}
// 将10位时间戳转换为日期对象
function timestampToDate(timestamp) {
return new Date(parseInt(timestamp) * 1000);
}
// 将日期对象转换为ModifyTime格式字符串
function dateToModifyTimeStr(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
const hour = String(date.getHours()).padStart(2, '0');
const minute = String(date.getMinutes()).padStart(2, '0');
const second = String(date.getSeconds()).padStart(2, '0');
return `${year}${month}${day}${hour}${minute}${second}`;
}
// 将ModifyTime字符串转换为日期对象
function modifyTimeToDate(timeStr) {
if (!timeStr || timeStr.length !== 14) return null;
const year = parseInt(timeStr.substr(0, 4));
const month = parseInt(timeStr.substr(4, 2)) - 1;
const day = parseInt(timeStr.substr(6, 2));
const hour = parseInt(timeStr.substr(8, 2));
const minute = parseInt(timeStr.substr(10, 2));
const second = parseInt(timeStr.substr(12, 2));
return new Date(year, month, day, hour, minute, second);
}
// 检查时间是否在比赛期间
function isInMatchPeriod(timeStr, matchTimestamp) {
const time = modifyTimeToDate(timeStr);
if (!time || !matchTimestamp) return false;
const matchStart = timestampToDate(matchTimestamp);
const matchEnd = new Date(matchStart.getTime() + 2 * 60 * 60 * 1000); // 比赛开始后2小时
return time >= matchStart && time <= matchEnd;
}
// 获取公司赔率数据
async function fetchOddsData(company) {
try {
const response = await fetch(`/HandicapDataInterface.ashx?scheid=${scheduleId}&type=3&oddskind=0&companyid=${company.companyId}&isHalf=0`);
if (!response.ok) {
throw new Error(`HTTP状态码: ${response.status}`);
}
const data = await response.json();
// 过滤出HappenTime为空的数据
return {
company,
odds: data.filter(item => item.HappenTime === "")
};
} catch (error) {
alert(`获取${company.nameCn}数据失败: ${error.message}`);
return { company, odds: [] };
}
}
// 创建主表格
function createMainTable(companiesData, homeMatchTime, awayMatchTime) {
const table = document.createElement('table');
table.style.textAlign = 'center';
table.style.margin = '0 auto';
table.style.borderCollapse = 'collapse';
// 添加样式
const style = document.createElement('style');
style.textContent = `
.odds-table td, .odds-table th {
border: 1px solid #888;
}
.match-period {
background-color: #fee;
}
`;
document.head.appendChild(style);
table.className = 'odds-table';
// 准备所有行数据
let rows = [];
// 添加公司数据行
companiesData.forEach(companyData => {
if (companyData.odds.length > 0) {
// 按ModifyTime排序,取最早的记录
const sortedOdds = [...companyData.odds].sort((a, b) => b.ModifyTime.localeCompare(a.ModifyTime));
const earliestOdds = sortedOdds[sortedOdds.length - 1];
rows.push({
type: 'company',
time: earliestOdds.ModifyTime,
data: companyData,
odds: earliestOdds
});
}
});
// 添加比赛时间标记
const homeStart = timestampToDate(homeMatchTime);
const homeEnd = new Date(homeStart.getTime() + 2 * 60 * 60 * 1000);
const awayStart = timestampToDate(awayMatchTime);
const awayEnd = new Date(awayStart.getTime() + 2 * 60 * 60 * 1000);
rows.push({
type: 'match',
time: dateToModifyTimeStr(homeStart),
label: '主队比赛开始'
});
rows.push({
type: 'match',
time: dateToModifyTimeStr(homeEnd),
label: '主队比赛结束'
});
rows.push({
type: 'match',
time: dateToModifyTimeStr(awayStart),
label: '客队比赛开始'
});
rows.push({
type: 'match',
time: dateToModifyTimeStr(awayEnd),
label: '客队比赛结束'
});
// 按时间降序排序
rows.sort((a, b) => b.time.localeCompare(a.time));
// 创建表格行
rows.forEach(row => {
const tr = document.createElement('tr');
// 检查是否在比赛期间
const inHomeMatch = homeMatchTime && isInMatchPeriod(row.time, homeMatchTime);
const inAwayMatch = awayMatchTime && isInMatchPeriod(row.time, awayMatchTime);
if (inHomeMatch || inAwayMatch) {
tr.classList.add('match-period');
}
// 时间单元格
const timeCell = document.createElement('td');
timeCell.textContent = formatModifyTime(row.time);
tr.appendChild(timeCell);
// 公司名称单元格
const companyCell = document.createElement('td');
if (row.type === 'company') {
companyCell.textContent = row.data.company.nameCn;
}
if (row.type === 'match') {
companyCell.colSpan = '2';
companyCell.textContent = row.label;
}
tr.appendChild(companyCell);
// 复选框单元格
if (row.type === 'company') {
const checkboxCell = document.createElement('td');
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.style.position = 'initial';
checkbox.value = row.data.company.companyId;
checkbox.addEventListener('change', function () {
if (this.checked) {
selectedComp.push(row.data);
} else {
selectedComp = selectedComp.filter(c => c.company.companyId !== row.data.company.companyId);
}
});
checkboxCell.appendChild(checkbox);
tr.appendChild(checkboxCell);
}
table.appendChild(tr);
});
return table;
}
// 创建对比表格
function createComparisonTable(homeMatchTime, awayMatchTime) {
if (selectedComp.length === 0) {
alert('请先选择至少一个公司');
return null;
}
const table = document.createElement('table');
table.style.textAlign = 'center';
table.style.borderCollapse = 'collapse';
table.style.margin = '10px auto 0';
table.className = 'odds-table';
// 收集所有赔率数据
let allOdds = [];
selectedComp.forEach(companyData => {
companyData.odds.forEach(odd => {
allOdds.push({...odd, company: companyData.company});
});
});
// 获取所有时间点
const uniqueTimes = [...new Set(allOdds.map(odd => odd.ModifyTime))];
// 比赛时间点
const homeStart = timestampToDate(homeMatchTime);
const homeEnd = new Date(homeStart.getTime() + 2 * 60 * 60 * 1000);
const awayStart = timestampToDate(awayMatchTime);
const awayEnd = new Date(awayStart.getTime() + 2 * 60 * 60 * 1000);
const matchTimes = [
{ time: dateToModifyTimeStr(homeStart), label: '主队比赛开始' },
{ time: dateToModifyTimeStr(homeEnd), label: '主队比赛结束' },
{ time: dateToModifyTimeStr(awayStart), label: '客队比赛开始' },
{ time: dateToModifyTimeStr(awayEnd), label: '客队比赛结束' }
];
// 合并并排序所有时间点
const allTimes = [...uniqueTimes, ...matchTimes.map(mt => mt.time)];
const sortedTimes = [...new Set(allTimes)].sort((a, b) => b.localeCompare(a));
// 创建表头
const headerRow = document.createElement('tr');
const timeHeader = document.createElement('th');
timeHeader.textContent = '时间';
headerRow.appendChild(timeHeader);
// 添加各公司的列
selectedComp.forEach(companyData => {
const panKouHeader = document.createElement('th');
panKouHeader.textContent = `${companyData.company.nameCn}让球`;
headerRow.appendChild(panKouHeader);
const diffHeader = document.createElement('th');
diffHeader.textContent = `${companyData.company.nameCn}水差`;
headerRow.appendChild(diffHeader);
});
table.appendChild(headerRow);
// 创建数据行
sortedTimes.forEach(time => {
const tr = document.createElement('tr');
// 检查是否在比赛期间
const inHomeMatch = homeMatchTime && isInMatchPeriod(time, homeMatchTime);
const inAwayMatch = awayMatchTime && isInMatchPeriod(time, awayMatchTime);
if (inHomeMatch || inAwayMatch) {
tr.classList.add('match-period');
}
// 时间单元格
const timeCell = document.createElement('td');
timeCell.textContent = formatModifyTime(time);
tr.appendChild(timeCell);
// 各公司数据
selectedComp.forEach(companyData => {
// 让球数单元格
const panKouCell = document.createElement('td');
// 赔率差单元格
const diffCell = document.createElement('td');
// 查找该时间点的赔率数据
const odd = companyData.odds.find(o => o.ModifyTime === time);
if (odd) {
panKouCell.textContent = odd.PanKou + '⚽';
const diff = (parseFloat(odd.AwayOdds) - parseFloat(odd.HomeOdds)).toFixed(2);
diffCell.textContent = diff;
}
tr.appendChild(panKouCell);
tr.appendChild(diffCell);
});
table.appendChild(tr);
});
return table;
}
// 主函数
async function init() {
try {
// 获取所有公司的赔率数据
const companiesData = await Promise.all(companies.map(fetchOddsData));
// 过滤有数据的公司
const validData = companiesData.filter(data => data.odds.length > 0);
// 获取主客队上一场比赛时间
const homeMatchTime = jsonData?.nearMatches?.homeMatches?.matches?.[0]?.matchTime || "";
const awayMatchTime = jsonData?.nearMatches?.awayMatches?.matches?.[0]?.matchTime || "";
// 创建主表格
const mainTable = createMainTable(validData, homeMatchTime, awayMatchTime);
// 创建对比按钮
const compareBtn = document.createElement('button');
compareBtn.textContent = '对比选中的公司';
compareBtn.style.background = '#bdf';
compareBtn.style.padding = '5px 10px';
compareBtn.style.marginTop = '10px';
compareBtn.addEventListener('click', () => {
// 移除已存在的对比表格
const oldTable = document.getElementById('comparison-table');
if (oldTable) oldTable.remove();
// 创建新对比表格
const comparisonTable = createComparisonTable(homeMatchTime, awayMatchTime);
if (comparisonTable) {
comparisonTable.id = 'comparison-table';
compareBtn.parentNode.insertBefore(comparisonTable, compareBtn.nextSibling);
}
});
// 创建容器并添加到页面
const container = document.createElement('div');
container.style.textAlign = 'center';
container.style.fontSize = '16px'
container.appendChild(mainTable);
container.appendChild(compareBtn);
const contentDiv = document.getElementById('content');
if (contentDiv) {
if (contentDiv.firstChild) {
contentDiv.insertBefore(container, contentDiv.firstChild);
} else {
contentDiv.appendChild(container);
}
} else {
document.body.insertBefore(container, document.body.firstChild);
}
} catch (error) {
alert(`脚本执行出错: ${error.message}`);
console.error(error);
}
}
// 启动脚本
init();
})();