flaresolver fix

This commit is contained in:
salvacybersec
2025-11-13 06:31:10 +03:00
parent fc64184f5f
commit 327beae747

View File

@@ -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: