Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import time
- import datetime
- import xml.etree.ElementTree as ET
- from selenium import webdriver
- from selenium.webdriver.chrome.options import Options
- from selenium.webdriver.common.by import By
- from selenium.webdriver.support.ui import WebDriverWait
- from selenium.webdriver.support import expected_conditions as EC
- # -----------------------------
- # Configuration
- # -----------------------------
- PEACOCK_URL = "https://www.peacocktv.com/watch/sports/live-and-upcoming"
- EPG_FILE = "peacock_epg_debug.xml"
- NUM_CHANNELS = 7
- EVENT_DURATION_HOURS = 4.5
- END_HOUR = 4 # End EPG at 4 AM next day
- # -----------------------------
- # Setup Chrome options
- # -----------------------------
- options = Options()
- options.add_argument(r"user-data-dir=C:\Users\YourUser\AppData\Local\Google\Chrome\User Data") # update your path
- options.add_argument(r'--profile-directory=Default')
- # options.add_argument("--headless=new") # remove comment to hide browser
- options.add_argument("--disable-gpu")
- options.add_argument("--no-sandbox")
- options.add_argument("--disable-dev-shm-usage")
- driver = webdriver.Chrome(options=options)
- driver.get(PEACOCK_URL)
- # -----------------------------
- # Wait for page to load and scroll
- # -----------------------------
- wait = WebDriverWait(driver, 20)
- driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
- time.sleep(2)
- cards = wait.until(EC.presence_of_all_elements_located(
- (By.CSS_SELECTOR, "div[data-testid='metadata-container']")
- ))
- print(f"Found {len(cards)} event cards on the page.")
- # -----------------------------
- # Scrape events
- # -----------------------------
- events = []
- for i, card in enumerate(cards, start=1):
- try:
- # Title
- title_elem = card.find_element(By.CSS_SELECTOR, "h4[data-testid='title']")
- title_text = title_elem.text.strip()
- # Sport type (first span inside metadata-container)
- span_elems = card.find_elements(By.TAG_NAME, "span")
- sport_text = "Sports"
- if span_elems:
- sport_text = span_elems[0].text.strip()
- full_title = f"{sport_text} - {title_text}"
- # Date and Time
- event_date = None
- event_time = None
- for sp in span_elems:
- t = sp.text.strip()
- t_lower = t.lower()
- # Handle Today / Tomorrow
- if t_lower == "today":
- event_date = datetime.date.today()
- elif t_lower == "tomorrow":
- event_date = datetime.date.today() + datetime.timedelta(days=1)
- # Time like 7:50 am
- elif ":" in t:
- try:
- event_time = datetime.datetime.strptime(t, "%I:%M %p").time()
- except:
- continue
- # Date like September 4
- elif any(month in t for month in [
- "January","February","March","April","May","June",
- "July","August","September","October","November","December"
- ]):
- try:
- event_date = datetime.datetime.strptime(t, "%B %d").date()
- event_date = event_date.replace(year=datetime.datetime.now().year)
- except:
- continue
- # fallback to today if missing
- if event_date is None:
- event_date = datetime.date.today()
- if event_time is None:
- event_time = datetime.datetime.now().time()
- start = datetime.datetime.combine(event_date, event_time)
- end = start + datetime.timedelta(hours=EVENT_DURATION_HOURS)
- events.append({"title": full_title, "start": start, "end": end})
- print(f"[{i}] {full_title} | starts {start} | ends {end}")
- except Exception as e:
- print(f"Skipped card {i}: {e}")
- driver.quit()
- # -----------------------------
- # Build XMLTV structure
- # -----------------------------
- tv = ET.Element("tv")
- channels = []
- for i in range(NUM_CHANNELS):
- channel_id = f"peacocksports{i+1}"
- channels.append({"id": channel_id, "schedule": []})
- ch_elem = ET.SubElement(tv, "channel", id=channel_id)
- ET.SubElement(ch_elem, "display-name").text = f"Peacock Sports {i+1}"
- # Place events into channels, avoiding overlap
- for event in sorted(events, key=lambda x: x["start"]):
- placed = False
- for ch in channels:
- if not ch["schedule"] or ch["schedule"][-1]["end"] <= event["start"]:
- ch["schedule"].append(event)
- placed = True
- break
- if not placed:
- channels[0]["schedule"].append(event)
- # Fill gaps and generate XML
- for ch in channels:
- time_pointer = datetime.datetime.now()
- end_of_day = time_pointer.replace(hour=END_HOUR, minute=0, second=0, microsecond=0) + datetime.timedelta(days=1)
- for prog in ch["schedule"]:
- if prog["start"] > time_pointer:
- programme = ET.SubElement(tv, "programme", {
- "start": time_pointer.strftime("%Y%m%d%H%M%S"),
- "stop": prog["start"].strftime("%Y%m%d%H%M%S"),
- "channel": ch["id"]
- })
- ET.SubElement(programme, "title", lang="en").text = "Signed Off"
- programme = ET.SubElement(tv, "programme", {
- "start": prog["start"].strftime("%Y%m%d%H%M%S"),
- "stop": prog["end"].strftime("%Y%m%d%H%M%S"),
- "channel": ch["id"]
- })
- ET.SubElement(programme, "title", lang="en").text = prog["title"]
- time_pointer = prog["end"]
- if time_pointer < end_of_day:
- programme = ET.SubElement(tv, "programme", {
- "start": time_pointer.strftime("%Y%m%d%H%M%S"),
- "stop": end_of_day.strftime("%Y%m%d%H%M%S"),
- "channel": ch["id"]
- })
- ET.SubElement(programme, "title", lang="en").text = "Signed Off"
- # Save XML
- tree = ET.ElementTree(tv)
- with open(EPG_FILE, "wb") as f:
- tree.write(f, encoding="utf-8", xml_declaration=True)
- print(f"✅ Created {EPG_FILE} with {NUM_CHANNELS} channels and {len(events)} events.")
Advertisement
Add Comment
Please, Sign In to add comment