Spaces:
Running
Running
Fix: shorts @baodantri+@baosuckhoedoisong sorted newest first, genk AI parallel OG fetch for all missing images
Browse files
main.py
CHANGED
|
@@ -176,14 +176,17 @@ def _yt_channel_shorts(channel, count=15):
|
|
| 176 |
return videos
|
| 177 |
except:return[]
|
| 178 |
def scrape_shorts():
|
| 179 |
-
"""Fetch shorts from @baodantri7941
|
| 180 |
vids=[]
|
| 181 |
-
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
|
|
|
|
|
|
|
|
|
| 187 |
return vids[:20]
|
| 188 |
|
| 189 |
# ===== LIVESCORE =====
|
|
@@ -349,8 +352,14 @@ def scrape_dantri_congnghe():
|
|
| 349 |
if len(arts)>=15:break
|
| 350 |
return arts
|
| 351 |
except:return[]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 352 |
def scrape_genk_ai():
|
| 353 |
-
"""Scrape AI articles from genk.vn - readable in-app"""
|
| 354 |
try:
|
| 355 |
r=requests.get("https://genk.vn/ai.chn",headers=HEADERS,timeout=15)
|
| 356 |
if r.status_code!=200:return[]
|
|
@@ -372,15 +381,18 @@ def scrape_genk_ai():
|
|
| 372 |
img_src=s;break
|
| 373 |
if img_src:break
|
| 374 |
container=container.parent
|
| 375 |
-
seen.add(href)
|
| 376 |
-
if not img_src:
|
| 377 |
-
try:
|
| 378 |
-
og_r=requests.get(href,headers=HEADERS,timeout=8);og_r.encoding="utf-8"
|
| 379 |
-
og_soup=BeautifulSoup(og_r.text,"lxml");og_tag=og_soup.find("meta",property="og:image")
|
| 380 |
-
if og_tag:img_src=og_tag.get("content","")
|
| 381 |
-
except:pass
|
| 382 |
-
articles.append({"title":title,"link":href,"img":img_src,"source":"genk"})
|
| 383 |
if len(articles)>=30:break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 384 |
return articles
|
| 385 |
except:return[]
|
| 386 |
|
|
|
|
| 176 |
return videos
|
| 177 |
except:return[]
|
| 178 |
def scrape_shorts():
|
| 179 |
+
"""Fetch shorts from @baodantri7941 + @baosuckhoedoisongboyte, sorted newest first"""
|
| 180 |
vids=[]
|
| 181 |
+
with ThreadPoolExecutor(2) as ex:
|
| 182 |
+
futs=[ex.submit(_yt_channel_shorts,ch,12) for ch in ["baodantri7941","baosuckhoedoisongboyte"]]
|
| 183 |
+
for f in as_completed(futs):
|
| 184 |
+
try:
|
| 185 |
+
r=f.result()
|
| 186 |
+
if r:vids.extend(r)
|
| 187 |
+
except:pass
|
| 188 |
+
# yt-dlp returns newest first per channel; interleave to keep chronological
|
| 189 |
+
vids.sort(key=lambda x:x.get("id",""),reverse=True)
|
| 190 |
return vids[:20]
|
| 191 |
|
| 192 |
# ===== LIVESCORE =====
|
|
|
|
| 352 |
if len(arts)>=15:break
|
| 353 |
return arts
|
| 354 |
except:return[]
|
| 355 |
+
def _fetch_og_image(url):
|
| 356 |
+
try:
|
| 357 |
+
r=requests.get(url,headers=HEADERS,timeout=6);r.encoding="utf-8"
|
| 358 |
+
soup=BeautifulSoup(r.text,"lxml");og=soup.find("meta",property="og:image")
|
| 359 |
+
return og.get("content","") if og else ""
|
| 360 |
+
except:return ""
|
| 361 |
def scrape_genk_ai():
|
| 362 |
+
"""Scrape AI articles from genk.vn - readable in-app, all with images"""
|
| 363 |
try:
|
| 364 |
r=requests.get("https://genk.vn/ai.chn",headers=HEADERS,timeout=15)
|
| 365 |
if r.status_code!=200:return[]
|
|
|
|
| 381 |
img_src=s;break
|
| 382 |
if img_src:break
|
| 383 |
container=container.parent
|
| 384 |
+
seen.add(href);articles.append({"title":title,"link":href,"img":img_src,"source":"genk"})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 385 |
if len(articles)>=30:break
|
| 386 |
+
# Fetch OG images in parallel for articles missing thumbnails
|
| 387 |
+
missing=[a for a in articles if not a["img"]]
|
| 388 |
+
if missing:
|
| 389 |
+
with ThreadPoolExecutor(6) as ex:
|
| 390 |
+
futs={ex.submit(_fetch_og_image,a["link"]):a for a in missing}
|
| 391 |
+
for f in as_completed(futs):
|
| 392 |
+
try:
|
| 393 |
+
img=f.result()
|
| 394 |
+
if img:futs[f]["img"]=img
|
| 395 |
+
except:pass
|
| 396 |
return articles
|
| 397 |
except:return[]
|
| 398 |
|