Spaces:
Running
Running
Fix WC highlights: direct scrape from xemlaibongda.top/the-gioi/world-cup
Browse files- static/wc2026_v2.js +57 -17
static/wc2026_v2.js
CHANGED
|
@@ -80,7 +80,6 @@ function renderWCStandings(el){
|
|
| 80 |
el.innerHTML=WC_CSS+'<div class="wc-bxh">'+d.html+'</div>';
|
| 81 |
const box=el.querySelector('.wc-bxh');
|
| 82 |
if(box){
|
| 83 |
-
// Insert a column-header row right after each group title so stats are labeled
|
| 84 |
box.querySelectorAll('.title-table, h6').forEach(t=>{
|
| 85 |
if(t.nextElementSibling && t.nextElementSibling.classList.contains('bxh-head'))return;
|
| 86 |
const head=document.createElement('div');
|
|
@@ -92,7 +91,6 @@ function renderWCStandings(el){
|
|
| 92 |
el.querySelectorAll('a').forEach(a=>a.addEventListener('click',e=>e.preventDefault()));
|
| 93 |
return;
|
| 94 |
}
|
| 95 |
-
// Self-calculate from fixtures
|
| 96 |
const fx=_wc2026Data.fixtures||{};const matches=fx.matches||[];
|
| 97 |
const gm=matches.filter(m=>m.group&&m.group.toLowerCase().includes('group'));
|
| 98 |
if(!gm.length){el.innerHTML='<div class="loading">BXH cập nhật khi giải bắt đầu 11/06/2026<br><small style="color:#6a9fca">🔴 Livescore tự động</small></div>';return;}
|
|
@@ -109,29 +107,71 @@ function renderWCStats(el){
|
|
| 109 |
else el.innerHTML='<div class="loading">Thống kê cập nhật khi giải bắt đầu<br><small style="color:#6a9fca">Vua phá lưới · Kiến tạo · Thẻ phạt</small></div>';
|
| 110 |
}
|
| 111 |
|
| 112 |
-
// === HIGHLIGHTS
|
|
|
|
| 113 |
async function renderWCHighlights(el){
|
| 114 |
-
el.innerHTML='<div class="loading">Đang tải highlight...</div>';
|
| 115 |
try{
|
| 116 |
-
//
|
| 117 |
-
const[
|
| 118 |
-
fetch('/
|
| 119 |
-
fetch('/
|
| 120 |
]);
|
| 121 |
-
|
| 122 |
-
const
|
| 123 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
let h='<div style="display:grid;grid-template-columns:repeat(2,1fr);gap:6px;max-height:450px;overflow-y:auto;padding:4px">';
|
| 125 |
-
all.
|
| 126 |
-
const league=v._league==='WC'?'world-cup':'friendly';
|
| 127 |
const badge=v._league==='WC'?'🌍 WC':'🤝 Friendly';
|
| 128 |
-
h+=`<div style="cursor:pointer;border-radius:6px;overflow:hidden;background:#0a1520" onclick="openHighlightFeed('${
|
| 129 |
-
h+=`<div style="position:relative;aspect-ratio:16/9;background:#1a2a3a">${v.img?`<img src="${esc(v.img)}" style="width:100%;height:100%;object-fit:cover">`:''}<div class="card-play">▶</div></div>`;
|
| 130 |
h+=`<div style="padding:4px 6px"><span style="font-size:8px;color:#f0c040">${badge}</span><div style="font-size:10px;color:#ccc;line-height:1.2;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden">${esc(v.title)}</div></div>`;
|
| 131 |
h+='</div>';
|
| 132 |
});
|
| 133 |
h+='</div>';el.innerHTML=h;
|
| 134 |
-
}catch(e){
|
|
|
|
|
|
|
| 135 |
}
|
| 136 |
|
| 137 |
// === LIVE AUTO-REFRESH (90s) ===
|
|
@@ -145,4 +185,4 @@ function startWCLiveRefresh(){
|
|
| 145 |
}catch(e){}
|
| 146 |
},90000);
|
| 147 |
}
|
| 148 |
-
setTimeout(startWCLiveRefresh,5000);
|
|
|
|
| 80 |
el.innerHTML=WC_CSS+'<div class="wc-bxh">'+d.html+'</div>';
|
| 81 |
const box=el.querySelector('.wc-bxh');
|
| 82 |
if(box){
|
|
|
|
| 83 |
box.querySelectorAll('.title-table, h6').forEach(t=>{
|
| 84 |
if(t.nextElementSibling && t.nextElementSibling.classList.contains('bxh-head'))return;
|
| 85 |
const head=document.createElement('div');
|
|
|
|
| 91 |
el.querySelectorAll('a').forEach(a=>a.addEventListener('click',e=>e.preventDefault()));
|
| 92 |
return;
|
| 93 |
}
|
|
|
|
| 94 |
const fx=_wc2026Data.fixtures||{};const matches=fx.matches||[];
|
| 95 |
const gm=matches.filter(m=>m.group&&m.group.toLowerCase().includes('group'));
|
| 96 |
if(!gm.length){el.innerHTML='<div class="loading">BXH cập nhật khi giải bắt đầu 11/06/2026<br><small style="color:#6a9fca">🔴 Livescore tự động</small></div>';return;}
|
|
|
|
| 107 |
else el.innerHTML='<div class="loading">Thống kê cập nhật khi giải bắt đầu<br><small style="color:#6a9fca">Vua phá lưới · Kiến tạo · Thẻ phạt</small></div>';
|
| 108 |
}
|
| 109 |
|
| 110 |
+
// === HIGHLIGHTS - Direct scrape from xemlaibongda.top/the-gioi/world-cup ===
|
| 111 |
+
// Also loads Friendly from /giai-khac/friendly
|
| 112 |
async function renderWCHighlights(el){
|
| 113 |
+
el.innerHTML='<div class="loading">Đang tải highlight từ xemlaibongda.top...</div>';
|
| 114 |
try{
|
| 115 |
+
// Direct scrape from xemlaibongda.top — bypass backend for reliability
|
| 116 |
+
const [wcHtml, frHtml] = await Promise.all([
|
| 117 |
+
fetch('https://xemlaibongda.top/the-gioi/world-cup', {signal: AbortSignal.timeout(15000)}).then(r=>r.ok?r.text():'').catch(()=>''),
|
| 118 |
+
fetch('https://xemlaibongda.top/giai-khac/friendly', {signal: AbortSignal.timeout(15000)}).then(r=>r.ok?r.text():'').catch(()=>'')
|
| 119 |
]);
|
| 120 |
+
|
| 121 |
+
const parseVideos = (html) => {
|
| 122 |
+
if (!html) return [];
|
| 123 |
+
const vids = [];
|
| 124 |
+
const seen = new Set();
|
| 125 |
+
// Match all article/video links with thumbnails
|
| 126 |
+
const re = /<a[^>]+href=["'](\/[^"']*\/video\/[^"']+)["'][^>]*>[\s\S]*?<img[^>]+src=["']([^"']+)["'][^>]*>[\s\S]*?<[^>]+class=["'][^"']*title[^"']*["'][^>]*>([^<]+)</gi;
|
| 127 |
+
let m;
|
| 128 |
+
while ((m = re.exec(html)) !== null) {
|
| 129 |
+
const link = 'https://xemlaibongda.top' + m[1].trim();
|
| 130 |
+
const img = m[2].trim();
|
| 131 |
+
const title = m[3].trim();
|
| 132 |
+
if (link && !seen.has(link) && title.length > 3) {
|
| 133 |
+
seen.add(link);
|
| 134 |
+
vids.push({ link, img, title });
|
| 135 |
+
}
|
| 136 |
+
if (vids.length >= 24) break;
|
| 137 |
+
}
|
| 138 |
+
// Fallback: simpler regex if first pattern fails
|
| 139 |
+
if (vids.length === 0) {
|
| 140 |
+
const re2 = /<a[^>]+href=["'](\/[^"']*\/video\/[^"']+)["'][^>]*>[\s\S]*?([^<]{8,})<\/a>/gi;
|
| 141 |
+
while ((m = re2.exec(html)) !== null) {
|
| 142 |
+
const link = 'https://xemlaibongda.top' + m[1].trim();
|
| 143 |
+
const title = m[2].trim();
|
| 144 |
+
if (link && !seen.has(link) && title.length > 5) {
|
| 145 |
+
seen.add(link);
|
| 146 |
+
vids.push({ link, img: '', title });
|
| 147 |
+
}
|
| 148 |
+
if (vids.length >= 24) break;
|
| 149 |
+
}
|
| 150 |
+
}
|
| 151 |
+
return vids;
|
| 152 |
+
};
|
| 153 |
+
|
| 154 |
+
const wcVids = parseVideos(wcHtml).map((v,i)=>({...v,_league:'WC',_li:i}));
|
| 155 |
+
const frVids = parseVideos(frHtml).map((v,i)=>({...v,_league:'Friendly',_li:i}));
|
| 156 |
+
const all = [...wcVids, ...frVids];
|
| 157 |
+
|
| 158 |
+
if(!all.length){
|
| 159 |
+
el.innerHTML='<div class="loading">Chưa có highlight World Cup / Giao hữu</div>';
|
| 160 |
+
return;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
let h='<div style="display:grid;grid-template-columns:repeat(2,1fr);gap:6px;max-height:450px;overflow-y:auto;padding:4px">';
|
| 164 |
+
all.forEach((v,i)=>{
|
|
|
|
| 165 |
const badge=v._league==='WC'?'🌍 WC':'🤝 Friendly';
|
| 166 |
+
h+=`<div style="cursor:pointer;border-radius:6px;overflow:hidden;background:#0a1520" onclick="openHighlightFeed('${v._league==='WC'?'world-cup':'friendly'}',${v._li},'${esc(v.link)}')">`;
|
| 167 |
+
h+=`<div style="position:relative;aspect-ratio:16/9;background:#1a2a3a">${v.img?`<img src="${esc(v.img)}" style="width:100%;height:100%;object-fit:cover" onerror="this.style.display='none'">`:''}<div class="card-play">▶</div></div>`;
|
| 168 |
h+=`<div style="padding:4px 6px"><span style="font-size:8px;color:#f0c040">${badge}</span><div style="font-size:10px;color:#ccc;line-height:1.2;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden">${esc(v.title)}</div></div>`;
|
| 169 |
h+='</div>';
|
| 170 |
});
|
| 171 |
h+='</div>';el.innerHTML=h;
|
| 172 |
+
}catch(e){
|
| 173 |
+
el.innerHTML='<div class="loading">Lỗi tải highlight: '+esc(e.message)+'</div>';
|
| 174 |
+
}
|
| 175 |
}
|
| 176 |
|
| 177 |
// === LIVE AUTO-REFRESH (90s) ===
|
|
|
|
| 185 |
}catch(e){}
|
| 186 |
},90000);
|
| 187 |
}
|
| 188 |
+
setTimeout(startWCLiveRefresh,5000);
|