init
This commit is contained in:
53
backend/app/netflix.py
Normal file
53
backend/app/netflix.py
Normal file
@@ -0,0 +1,53 @@
|
||||
"""Die echte Netflix-Titel-ID aus TMDBs Watch-Seite lesen.
|
||||
|
||||
Die API liefert nur den Anbieternamen. Die Titel-ID steht ausschließlich im
|
||||
HTML der Watch-Seite, URL-kodiert im Weiterleitungslink von JustWatch.
|
||||
|
||||
Ohne sie bliebe nur eine Netflix-Titelsuche, und die geht ins Leere, sobald
|
||||
Netflix den Film anders nennt: "LIENZO" heißt dort "Die Leinwand".
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import re
|
||||
|
||||
import httpx
|
||||
|
||||
log = logging.getLogger("netflix")
|
||||
|
||||
TITLE_ID = re.compile(r"netflix\.com%2Ftitle%2F(\d+)")
|
||||
UA = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/131.0"
|
||||
# Zu dichte Abrufe drosselt TMDB. Die Seite kommt dann mit Status 200, aber
|
||||
# ohne Anbieterblock. Filme ohne ID versucht der nächste Sync erneut.
|
||||
PAUSE = 1.5
|
||||
|
||||
|
||||
def watch_url(movie_id):
|
||||
return f"https://www.themoviedb.org/movie/{movie_id}/watch?locale=DE"
|
||||
|
||||
|
||||
def title_url(netflix_id):
|
||||
return f"https://www.netflix.com/de/title/{netflix_id}"
|
||||
|
||||
|
||||
async def fetch_ids(movie_ids):
|
||||
"""Seriell, mit Pause. Gibt {tmdb_id: netflix_id} für alles Gefundene."""
|
||||
found = {}
|
||||
async with httpx.AsyncClient(
|
||||
headers={"User-Agent": UA}, timeout=60.0, follow_redirects=True
|
||||
) as http:
|
||||
for index, movie_id in enumerate(movie_ids, 1):
|
||||
try:
|
||||
resp = await http.get(watch_url(movie_id))
|
||||
# Mehrere IDs bedeuten mehrere Fassungen — Godzilla Minus One
|
||||
# liegt in Farbe und in Schwarzweiß. Die erste Kachel ist die
|
||||
# Hauptfassung.
|
||||
ids = TITLE_ID.findall(resp.text)
|
||||
if ids:
|
||||
found[movie_id] = ids[0]
|
||||
except httpx.HTTPError:
|
||||
log.warning("Watch-Seite nicht erreichbar: %s", movie_id)
|
||||
if index % 50 == 0:
|
||||
log.info(" %s/%s Watch-Seiten gelesen", index, len(movie_ids))
|
||||
await asyncio.sleep(PAUSE)
|
||||
return found
|
||||
Reference in New Issue
Block a user