flaresolver fix
This commit is contained in:
@@ -169,9 +169,13 @@ class TranscriptExtractor:
|
|||||||
|
|
||||||
def patched_get(session_self, url, **kwargs):
|
def patched_get(session_self, url, **kwargs):
|
||||||
"""requests.Session.get'i patch et - header'ları ekle ve FlareSolverr kullan"""
|
"""requests.Session.get'i patch et - header'ları ekle ve FlareSolverr kullan"""
|
||||||
# FlareSolverr kullanılıyorsa ve YouTube URL'si ise
|
# FlareSolverr'ı sadece video sayfası için kullan (transcript API endpoint'leri için değil)
|
||||||
if extractor_instance.use_flaresolverr and ('youtube.com' in url or 'youtu.be' in url):
|
# Transcript API endpoint'leri genellikle /api/timedtext gibi path'ler içerir
|
||||||
logger.debug(f"[FLARESOLVERR] YouTube isteği FlareSolverr üzerinden deneniyor: {url[:50]}...")
|
is_video_page = ('youtube.com/watch' in url or 'youtu.be/' in url) and '/api/' not in url
|
||||||
|
|
||||||
|
# FlareSolverr kullanılıyorsa ve video sayfası ise
|
||||||
|
if extractor_instance.use_flaresolverr and is_video_page:
|
||||||
|
logger.debug(f"[FLARESOLVERR] Video sayfası FlareSolverr üzerinden deneniyor: {url[:50]}...")
|
||||||
flaresolverr_response = extractor_instance._make_flaresolverr_request(url, 'GET', **kwargs)
|
flaresolverr_response = extractor_instance._make_flaresolverr_request(url, 'GET', **kwargs)
|
||||||
if flaresolverr_response:
|
if flaresolverr_response:
|
||||||
logger.debug(f"[FLARESOLVERR] ✅ FlareSolverr başarılı, response döndürülüyor")
|
logger.debug(f"[FLARESOLVERR] ✅ FlareSolverr başarılı, response döndürülüyor")
|
||||||
@@ -201,6 +205,9 @@ class TranscriptExtractor:
|
|||||||
return PatchedResponse(flaresolverr_response)
|
return PatchedResponse(flaresolverr_response)
|
||||||
else:
|
else:
|
||||||
logger.debug(f"[FLARESOLVERR] FlareSolverr yanıt vermedi, normal istek deneniyor")
|
logger.debug(f"[FLARESOLVERR] FlareSolverr yanıt vermedi, normal istek deneniyor")
|
||||||
|
elif extractor_instance.use_flaresolverr and ('youtube.com' in url or 'youtu.be' in url):
|
||||||
|
# Transcript API endpoint'leri için FlareSolverr kullanma, sadece header'ları ekle
|
||||||
|
logger.debug(f"[FLARESOLVERR] Transcript API endpoint'i tespit edildi, FlareSolverr atlanıyor: {url[:50]}...")
|
||||||
|
|
||||||
# Normal istek (header'ları ekle)
|
# Normal istek (header'ları ekle)
|
||||||
headers = kwargs.get('headers', {})
|
headers = kwargs.get('headers', {})
|
||||||
@@ -211,37 +218,10 @@ class TranscriptExtractor:
|
|||||||
|
|
||||||
def patched_post(session_self, url, **kwargs):
|
def patched_post(session_self, url, **kwargs):
|
||||||
"""requests.Session.post'i patch et - header'ları ekle ve FlareSolverr kullan"""
|
"""requests.Session.post'i patch et - header'ları ekle ve FlareSolverr kullan"""
|
||||||
# FlareSolverr kullanılıyorsa ve YouTube URL'si ise
|
# POST istekleri için FlareSolverr kullanma (genellikle API endpoint'leri)
|
||||||
|
# Sadece header'ları ekle
|
||||||
if extractor_instance.use_flaresolverr and ('youtube.com' in url or 'youtu.be' in url):
|
if extractor_instance.use_flaresolverr and ('youtube.com' in url or 'youtu.be' in url):
|
||||||
logger.debug(f"[FLARESOLVERR] YouTube POST isteği FlareSolverr üzerinden deneniyor: {url[:50]}...")
|
logger.debug(f"[FLARESOLVERR] POST isteği tespit edildi, FlareSolverr atlanıyor (sadece header'lar): {url[:50]}...")
|
||||||
flaresolverr_response = extractor_instance._make_flaresolverr_request(url, 'POST', **kwargs)
|
|
||||||
if flaresolverr_response:
|
|
||||||
logger.debug(f"[FLARESOLVERR] ✅ FlareSolverr başarılı, response döndürülüyor")
|
|
||||||
class PatchedResponse:
|
|
||||||
def __init__(self, flaresolverr_response):
|
|
||||||
self.status_code = flaresolverr_response.status_code
|
|
||||||
self.text = flaresolverr_response.text
|
|
||||||
self.content = flaresolverr_response.content
|
|
||||||
self.headers = flaresolverr_response.headers
|
|
||||||
self.url = flaresolverr_response.url
|
|
||||||
self.ok = 200 <= self.status_code < 300
|
|
||||||
|
|
||||||
def json(self):
|
|
||||||
import json
|
|
||||||
try:
|
|
||||||
return json.loads(self.text)
|
|
||||||
except:
|
|
||||||
return {}
|
|
||||||
|
|
||||||
def raise_for_status(self):
|
|
||||||
"""requests.Response.raise_for_status() uyumluluğu"""
|
|
||||||
if not self.ok:
|
|
||||||
from requests.exceptions import HTTPError
|
|
||||||
raise HTTPError(f"{self.status_code} Client Error: {self.text[:100]}", response=self)
|
|
||||||
|
|
||||||
return PatchedResponse(flaresolverr_response)
|
|
||||||
else:
|
|
||||||
logger.debug(f"[FLARESOLVERR] FlareSolverr yanıt vermedi, normal istek deneniyor")
|
|
||||||
|
|
||||||
# Normal istek (header'ları ekle)
|
# Normal istek (header'ları ekle)
|
||||||
headers = kwargs.get('headers', {})
|
headers = kwargs.get('headers', {})
|
||||||
@@ -384,6 +364,40 @@ class TranscriptExtractor:
|
|||||||
error_msg = str(e)
|
error_msg = str(e)
|
||||||
error_type = type(e).__name__
|
error_type = type(e).__name__
|
||||||
|
|
||||||
|
# AttributeError: 'NoneType' object has no attribute 'get' hatası
|
||||||
|
# Bu genellikle FlareSolverr'dan dönen HTML'in parse edilememesinden kaynaklanır
|
||||||
|
if "AttributeError" in error_type and "'NoneType' object has no attribute 'get'" in error_msg:
|
||||||
|
logger.error(f"[TRANSCRIPT] ❌ Video {video_id} parse hatası: FlareSolverr HTML'i parse edilemedi")
|
||||||
|
logger.error(f"[TRANSCRIPT] Hata detayları: {error_type} - {error_msg[:300]}")
|
||||||
|
logger.error(f"[TRANSCRIPT] FlareSolverr HTML formatı youtube-transcript-api ile uyumsuz olabilir")
|
||||||
|
|
||||||
|
# FlareSolverr'ı geçici olarak devre dışı bırak ve normal istek dene
|
||||||
|
if attempt < max_retries:
|
||||||
|
logger.warning(f"[TRANSCRIPT] ⚠️ FlareSolverr'ı atlayıp normal istek deneniyor (Deneme {attempt + 1}/{max_retries + 1})")
|
||||||
|
# FlareSolverr'ı geçici olarak devre dışı bırak
|
||||||
|
original_use_flaresolverr = self.use_flaresolverr
|
||||||
|
self.use_flaresolverr = False
|
||||||
|
try:
|
||||||
|
# Normal istek dene
|
||||||
|
api = YouTubeTranscriptApi()
|
||||||
|
fetched_transcript = api.fetch(video_id, languages=languages)
|
||||||
|
transcript = fetched_transcript.to_raw_data()
|
||||||
|
transcript_count = len(transcript) if transcript else 0
|
||||||
|
logger.info(f"[TRANSCRIPT] ✅ Video {video_id} transcript'i normal istek ile başarıyla çıkarıldı ({transcript_count} segment)")
|
||||||
|
# FlareSolverr'ı tekrar etkinleştir
|
||||||
|
self.use_flaresolverr = original_use_flaresolverr
|
||||||
|
return transcript
|
||||||
|
except Exception as e2:
|
||||||
|
# FlareSolverr'ı tekrar etkinleştir
|
||||||
|
self.use_flaresolverr = original_use_flaresolverr
|
||||||
|
logger.error(f"[TRANSCRIPT] ❌ Normal istek de başarısız: {type(e2).__name__} - {str(e2)[:200]}")
|
||||||
|
# Retry yap
|
||||||
|
if attempt < max_retries:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
logger.error(f"[TRANSCRIPT] ❌ Tüm denemeler başarısız (FlareSolverr ve normal istek)")
|
||||||
|
return None
|
||||||
|
|
||||||
# YouTubeDataUnparsable hatası için retry yap
|
# YouTubeDataUnparsable hatası için retry yap
|
||||||
if "YouTubeDataUnparsable" in error_type or "Unparsable" in error_type:
|
if "YouTubeDataUnparsable" in error_type or "Unparsable" in error_type:
|
||||||
if attempt < max_retries:
|
if attempt < max_retries:
|
||||||
|
|||||||
Reference in New Issue
Block a user