bep40 commited on
Commit
4cc38e4
·
verified ·
1 Parent(s): 9e9ccf4

Upload vtv_scraper.py

Browse files
Files changed (1) hide show
  1. vtv_scraper.py +24 -27
vtv_scraper.py CHANGED
@@ -1,6 +1,7 @@
1
  """
2
  VTV Channels Scraper
3
- Fetches stream URLs from hd.xemtv.net for VTV1-VTV10 + VTV Can Tho
 
4
  """
5
  import requests, re, time, threading
6
  from bs4 import BeautifulSoup
@@ -11,34 +12,31 @@ UA = {
11
  "Referer": "https://hd.xemtv.net/",
12
  }
13
 
14
- # Channel page URLs on xemtv.net
15
  XEMTV_CHANNELS = {
16
  "VTV1": "https://hd.xemtv.net/kenh-vtv1-truc-tuyen-hot.html",
17
  "VTV2": "https://hd.xemtv.net/kenh-vtv2-truc-tuyen-hot.html",
18
  "VTV3": "https://hd.xemtv.net/kenh-vtv3-truc-tuyen-hot.html",
19
  "VTV4": "https://hd.xemtv.net/kenh-vtv4-truc-tuyen-hot.html",
20
  "VTV5": "https://hd.xemtv.net/kenh-vtv5-truc-tuyen-hot.html",
21
- "VTV CẦN THƠ": "https://hd.xemtv.net/kenh-vtv-can-tho-truc-tuyen-hot.html",
22
- "VTV6": "https://hd.xemtv.net/kenh-vtv6-truc-tuyen-hot.html",
23
  "VTV7": "https://hd.xemtv.net/kenh-vtv7-truc-tuyen-hot.html",
24
  "VTV8": "https://hd.xemtv.net/kenh-vtv8-truc-tuyen-hot.html",
25
  "VTV9": "https://hd.xemtv.net/kenh-vtv9-truc-tuyen-hot.html",
26
- "VTV10": "https://hd.xemtv.net/kenh-vtv10-truc-tuyen-hot.html",
27
  }
28
 
29
- # CDN fallback streams (HoichainTV)
 
30
  CDN_STREAMS = {
31
- "VTV1": "https://vips-livecdn.hoichanhtv.com/vtv1/index.m3u8",
32
- "VTV2": "https://vips-livecdn.hoichanhtv.com/vtv2/index.m3u8",
33
- "VTV3": "https://vips-livecdn.hoichanhtv.com/vtv3/index.m3u8",
34
- "VTV4": "https://vips-livecdn.hoichanhtv.com/vtv4/index.m3u8",
35
- "VTV5": "https://vips-livecdn.hoichanhtv.com/vtv5/index.m3u8",
36
- "VTV CẦN THƠ": "https://vips-livecdn.hoichanhtv.com/vtv6/index.m3u8",
37
- "VTV6": "https://vips-livecdn.hoichanhtv.com/vtv6/index.m3u8",
38
- "VTV7": "https://vips-livecdn.hoichanhtv.com/vtv7/index.m3u8",
39
- "VTV8": "https://vips-livecdn.hoichanhtv.com/vtv8/index.m3u8",
40
- "VTV9": "https://vips-livecdn.hoichanhtv.com/vtv9/index.m3u8",
41
- "VTV10": "https://vips-livecdn.hoichanhtv.com/vtv10/index.m3u8",
42
  }
43
 
44
  _vtv_cache = {}
@@ -78,7 +76,6 @@ def extract_m3u8_from_html(html):
78
  m = re.search(pat, html, re.IGNORECASE)
79
  if m:
80
  url = m.group(1).strip()
81
- # Validate it looks like a real m3u8
82
  if '.m3u8' in url and len(url) > 20:
83
  return url
84
  return None
@@ -87,28 +84,28 @@ def extract_m3u8_from_html(html):
87
  def fetch_vtv_stream(channel_name):
88
  """Fetch m3u8 stream URL for a VTV channel from xemtv.net."""
89
  channel_name = channel_name.upper().strip()
90
-
91
  # Normalize name
92
  name_map = {
93
  'VTVCT': 'VTV CẦN THƠ', 'VTV-CAN-THO': 'VTV CẦN THƠ',
94
- 'VTV CAN THO': 'VTV CẦN THƠ', 'VTVCT': 'VTV CẦN THƠ',
 
95
  }
96
  channel_name = name_map.get(channel_name, channel_name)
97
-
98
  # Check cache
99
  cached = _cached(channel_name)
100
  if cached:
101
  return cached
102
-
103
  page_url = XEMTV_CHANNELS.get(channel_name)
104
  if not page_url:
105
- # Try CDN fallback
106
  cdn = CDN_STREAMS.get(channel_name)
107
  if cdn:
108
  _set_cache(channel_name, cdn)
109
  return cdn
110
  return None
111
-
112
  try:
113
  r = requests.get(page_url, headers=UA, timeout=15, allow_redirects=True)
114
  if r.status_code == 200:
@@ -116,15 +113,15 @@ def fetch_vtv_stream(channel_name):
116
  if m3u8:
117
  _set_cache(channel_name, m3u8)
118
  return m3u8
119
- except Exception as e:
120
  pass
121
-
122
  # Fallback to CDN
123
  cdn = CDN_STREAMS.get(channel_name)
124
  if cdn:
125
  _set_cache(channel_name, cdn)
126
  return cdn
127
-
128
  return None
129
 
130
 
 
1
  """
2
  VTV Channels Scraper
3
+ Fetches stream URLs from hd.xemtv.net for VTV1-VTV9 + VTV Cần Thơ
4
+ Uses fptplay CDN as primary source (accessed via backend proxy with Referer header)
5
  """
6
  import requests, re, time, threading
7
  from bs4 import BeautifulSoup
 
12
  "Referer": "https://hd.xemtv.net/",
13
  }
14
 
15
+ # Channel page URLs on xemtv.net (for scraping)
16
  XEMTV_CHANNELS = {
17
  "VTV1": "https://hd.xemtv.net/kenh-vtv1-truc-tuyen-hot.html",
18
  "VTV2": "https://hd.xemtv.net/kenh-vtv2-truc-tuyen-hot.html",
19
  "VTV3": "https://hd.xemtv.net/kenh-vtv3-truc-tuyen-hot.html",
20
  "VTV4": "https://hd.xemtv.net/kenh-vtv4-truc-tuyen-hot.html",
21
  "VTV5": "https://hd.xemtv.net/kenh-vtv5-truc-tuyen-hot.html",
22
+ "VTV CẦN THƠ": "https://hd.xemtv.net/kenh-vtv10-truc-tuyen-hot.html",
 
23
  "VTV7": "https://hd.xemtv.net/kenh-vtv7-truc-tuyen-hot.html",
24
  "VTV8": "https://hd.xemtv.net/kenh-vtv8-truc-tuyen-hot.html",
25
  "VTV9": "https://hd.xemtv.net/kenh-vtv9-truc-tuyen-hot.html",
 
26
  }
27
 
28
+ # Primary CDN streams (fptplay) — these require Referer: https://fptplay.vn/
29
+ # The backend proxy (/api/proxy/hls) adds this header
30
  CDN_STREAMS = {
31
+ "VTV1": "https://live.fptplay53.net/fnxch2/vtv1hd_abr.smil/chunklist.m3u8",
32
+ "VTV2": "https://live.fptplay53.net/fnxch2/vtv2hd_abr.smil/chunklist.m3u8",
33
+ "VTV3": "https://live.fptplay53.net/fnxch2/vtv3hd_abr.smil/chunklist.m3u8",
34
+ "VTV4": "https://live.fptplay53.net/fnxch2/vtv4hd_abr.smil/chunklist.m3u8",
35
+ "VTV5": "https://live-a.fptplay53.net/live/media/VTV5HD/live_hls_avc/index.m3u8",
36
+ "VTV CẦN THƠ": "https://live.fptplay53.net/fnxch2/vtvcantho_abr.smil/chunklist.m3u8",
37
+ "VTV7": "https://live.fptplay53.net/fnxhd1/vtv7hd_vhls.smil/chunklist_b5000000.m3u8",
38
+ "VTV8": "https://live.fptplay53.net/epzhd1/vtv8hd_vhls.smil/chunklist.m3u8",
39
+ "VTV9": "https://live.fptplay53.net/fnxhd1/vtv9hd_vhls.smil/chunklist.m3u8",
 
 
40
  }
41
 
42
  _vtv_cache = {}
 
76
  m = re.search(pat, html, re.IGNORECASE)
77
  if m:
78
  url = m.group(1).strip()
 
79
  if '.m3u8' in url and len(url) > 20:
80
  return url
81
  return None
 
84
  def fetch_vtv_stream(channel_name):
85
  """Fetch m3u8 stream URL for a VTV channel from xemtv.net."""
86
  channel_name = channel_name.upper().strip()
87
+
88
  # Normalize name
89
  name_map = {
90
  'VTVCT': 'VTV CẦN THƠ', 'VTV-CAN-THO': 'VTV CẦN THƠ',
91
+ 'VTV CAN THO': 'VTV CẦN THƠ', 'VTV6': 'VTV CẦN THƠ',
92
+ 'VTCT': 'VTV CẦN THƠ',
93
  }
94
  channel_name = name_map.get(channel_name, channel_name)
95
+
96
  # Check cache
97
  cached = _cached(channel_name)
98
  if cached:
99
  return cached
100
+
101
  page_url = XEMTV_CHANNELS.get(channel_name)
102
  if not page_url:
 
103
  cdn = CDN_STREAMS.get(channel_name)
104
  if cdn:
105
  _set_cache(channel_name, cdn)
106
  return cdn
107
  return None
108
+
109
  try:
110
  r = requests.get(page_url, headers=UA, timeout=15, allow_redirects=True)
111
  if r.status_code == 200:
 
113
  if m3u8:
114
  _set_cache(channel_name, m3u8)
115
  return m3u8
116
+ except:
117
  pass
118
+
119
  # Fallback to CDN
120
  cdn = CDN_STREAMS.get(channel_name)
121
  if cdn:
122
  _set_cache(channel_name, cdn)
123
  return cdn
124
+
125
  return None
126
 
127