Guest User

Untitled

a guest
Aug 30th, 2025
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.01 KB | None | 0 0
  1. import time
  2. import datetime
  3. import xml.etree.ElementTree as ET
  4. from selenium import webdriver
  5. from selenium.webdriver.chrome.options import Options
  6. from selenium.webdriver.common.by import By
  7. from selenium.webdriver.support.ui import WebDriverWait
  8. from selenium.webdriver.support import expected_conditions as EC
  9.  
  10. # -----------------------------
  11. # Configuration
  12. # -----------------------------
  13. PEACOCK_URL = "https://www.peacocktv.com/watch/sports/live-and-upcoming"
  14. EPG_FILE = "peacock_epg_debug.xml"
  15. NUM_CHANNELS = 7
  16. EVENT_DURATION_HOURS = 4.5
  17. END_HOUR = 4 # End EPG at 4 AM next day
  18.  
  19. # -----------------------------
  20. # Setup Chrome options
  21. # -----------------------------
  22. options = Options()
  23. options.add_argument(r"user-data-dir=C:\Users\YourUser\AppData\Local\Google\Chrome\User Data") # update your path
  24. options.add_argument(r'--profile-directory=Default')
  25. # options.add_argument("--headless=new") # remove comment to hide browser
  26. options.add_argument("--disable-gpu")
  27. options.add_argument("--no-sandbox")
  28. options.add_argument("--disable-dev-shm-usage")
  29.  
  30. driver = webdriver.Chrome(options=options)
  31. driver.get(PEACOCK_URL)
  32.  
  33. # -----------------------------
  34. # Wait for page to load and scroll
  35. # -----------------------------
  36. wait = WebDriverWait(driver, 20)
  37. driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
  38. time.sleep(2)
  39.  
  40. cards = wait.until(EC.presence_of_all_elements_located(
  41. (By.CSS_SELECTOR, "div[data-testid='metadata-container']")
  42. ))
  43. print(f"Found {len(cards)} event cards on the page.")
  44.  
  45. # -----------------------------
  46. # Scrape events
  47. # -----------------------------
  48. events = []
  49.  
  50. for i, card in enumerate(cards, start=1):
  51. try:
  52. # Title
  53. title_elem = card.find_element(By.CSS_SELECTOR, "h4[data-testid='title']")
  54. title_text = title_elem.text.strip()
  55.  
  56. # Sport type (first span inside metadata-container)
  57. span_elems = card.find_elements(By.TAG_NAME, "span")
  58. sport_text = "Sports"
  59. if span_elems:
  60. sport_text = span_elems[0].text.strip()
  61.  
  62. full_title = f"{sport_text} - {title_text}"
  63.  
  64. # Date and Time
  65. event_date = None
  66. event_time = None
  67. for sp in span_elems:
  68. t = sp.text.strip()
  69. t_lower = t.lower()
  70. # Handle Today / Tomorrow
  71. if t_lower == "today":
  72. event_date = datetime.date.today()
  73. elif t_lower == "tomorrow":
  74. event_date = datetime.date.today() + datetime.timedelta(days=1)
  75. # Time like 7:50 am
  76. elif ":" in t:
  77. try:
  78. event_time = datetime.datetime.strptime(t, "%I:%M %p").time()
  79. except:
  80. continue
  81. # Date like September 4
  82. elif any(month in t for month in [
  83. "January","February","March","April","May","June",
  84. "July","August","September","October","November","December"
  85. ]):
  86. try:
  87. event_date = datetime.datetime.strptime(t, "%B %d").date()
  88. event_date = event_date.replace(year=datetime.datetime.now().year)
  89. except:
  90. continue
  91.  
  92. # fallback to today if missing
  93. if event_date is None:
  94. event_date = datetime.date.today()
  95. if event_time is None:
  96. event_time = datetime.datetime.now().time()
  97.  
  98. start = datetime.datetime.combine(event_date, event_time)
  99. end = start + datetime.timedelta(hours=EVENT_DURATION_HOURS)
  100.  
  101. events.append({"title": full_title, "start": start, "end": end})
  102. print(f"[{i}] {full_title} | starts {start} | ends {end}")
  103.  
  104. except Exception as e:
  105. print(f"Skipped card {i}: {e}")
  106.  
  107. driver.quit()
  108.  
  109. # -----------------------------
  110. # Build XMLTV structure
  111. # -----------------------------
  112. tv = ET.Element("tv")
  113. channels = []
  114.  
  115. for i in range(NUM_CHANNELS):
  116. channel_id = f"peacocksports{i+1}"
  117. channels.append({"id": channel_id, "schedule": []})
  118. ch_elem = ET.SubElement(tv, "channel", id=channel_id)
  119. ET.SubElement(ch_elem, "display-name").text = f"Peacock Sports {i+1}"
  120.  
  121. # Place events into channels, avoiding overlap
  122. for event in sorted(events, key=lambda x: x["start"]):
  123. placed = False
  124. for ch in channels:
  125. if not ch["schedule"] or ch["schedule"][-1]["end"] <= event["start"]:
  126. ch["schedule"].append(event)
  127. placed = True
  128. break
  129. if not placed:
  130. channels[0]["schedule"].append(event)
  131.  
  132. # Fill gaps and generate XML
  133. for ch in channels:
  134. time_pointer = datetime.datetime.now()
  135. end_of_day = time_pointer.replace(hour=END_HOUR, minute=0, second=0, microsecond=0) + datetime.timedelta(days=1)
  136.  
  137. for prog in ch["schedule"]:
  138. if prog["start"] > time_pointer:
  139. programme = ET.SubElement(tv, "programme", {
  140. "start": time_pointer.strftime("%Y%m%d%H%M%S"),
  141. "stop": prog["start"].strftime("%Y%m%d%H%M%S"),
  142. "channel": ch["id"]
  143. })
  144. ET.SubElement(programme, "title", lang="en").text = "Signed Off"
  145.  
  146. programme = ET.SubElement(tv, "programme", {
  147. "start": prog["start"].strftime("%Y%m%d%H%M%S"),
  148. "stop": prog["end"].strftime("%Y%m%d%H%M%S"),
  149. "channel": ch["id"]
  150. })
  151. ET.SubElement(programme, "title", lang="en").text = prog["title"]
  152. time_pointer = prog["end"]
  153.  
  154. if time_pointer < end_of_day:
  155. programme = ET.SubElement(tv, "programme", {
  156. "start": time_pointer.strftime("%Y%m%d%H%M%S"),
  157. "stop": end_of_day.strftime("%Y%m%d%H%M%S"),
  158. "channel": ch["id"]
  159. })
  160. ET.SubElement(programme, "title", lang="en").text = "Signed Off"
  161.  
  162. # Save XML
  163. tree = ET.ElementTree(tv)
  164. with open(EPG_FILE, "wb") as f:
  165. tree.write(f, encoding="utf-8", xml_declaration=True)
  166.  
  167. print(f"✅ Created {EPG_FILE} with {NUM_CHANNELS} channels and {len(events)} events.")
  168.  
Advertisement
Add Comment
Please, Sign In to add comment