Fix: Resolve gevent-Trio conflict on Mac by using Botasaurus subprocess
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
title: "애니 다운로더"
|
title: "애니 다운로더"
|
||||||
version: "0.6.8"
|
version: "0.6.9"
|
||||||
package_name: "anime_downloader"
|
package_name: "anime_downloader"
|
||||||
developer: "projectdx"
|
developer: "projectdx"
|
||||||
description: "anime downloader"
|
description: "anime downloader"
|
||||||
|
|||||||
54
lib/botasaurus_ohli24.py
Normal file
54
lib/botasaurus_ohli24.py
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Botasaurus 기반 Ohli24 HTML 페칭 스크립트
|
||||||
|
- gevent monkey-patching과 Trio 간의 충돌을 방지하기 위해 별도 프로세스로 실행
|
||||||
|
- JSON 출력으로 상위 프로세스(mod_ohli24)와 통신
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
def fetch_html(url, headers=None, proxy=None):
|
||||||
|
result = {"success": False, "html": "", "elapsed": 0}
|
||||||
|
start_time = time.time()
|
||||||
|
|
||||||
|
try:
|
||||||
|
from botasaurus.request import request as b_request
|
||||||
|
|
||||||
|
@b_request(headers=headers, use_stealth=True, proxy=proxy)
|
||||||
|
def fetch_url(request, data):
|
||||||
|
return request.get(data)
|
||||||
|
|
||||||
|
b_resp = fetch_url(url)
|
||||||
|
elapsed = time.time() - start_time
|
||||||
|
|
||||||
|
if b_resp and len(b_resp) > 10:
|
||||||
|
result.update({
|
||||||
|
"success": True,
|
||||||
|
"html": b_resp,
|
||||||
|
"elapsed": round(elapsed, 2)
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
result["error"] = f"Short response: {len(b_resp) if b_resp else 0} bytes"
|
||||||
|
result["elapsed"] = round(elapsed, 2)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
result["error"] = str(e)
|
||||||
|
result["traceback"] = traceback.format_exc()
|
||||||
|
result["elapsed"] = round(time.time() - start_time, 2)
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print(json.dumps({"success": False, "error": "Usage: python botasaurus_ohli24.py <url> [headers_json] [proxy]"}))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
target_url = sys.argv[1]
|
||||||
|
headers_arg = json.loads(sys.argv[2]) if len(sys.argv) > 2 and sys.argv[2] else None
|
||||||
|
proxy_arg = sys.argv[3] if len(sys.argv) > 3 and sys.argv[3] else None
|
||||||
|
|
||||||
|
res = fetch_html(target_url, headers_arg, proxy_arg)
|
||||||
|
print(json.dumps(res, ensure_ascii=False))
|
||||||
@@ -1950,20 +1950,48 @@ class LogicOhli24(AnimeModuleBase):
|
|||||||
# === [Layer 1: Botasaurus @request (빠름 - HTTP Request)] ===
|
# === [Layer 1: Botasaurus @request (빠름 - HTTP Request)] ===
|
||||||
if not response_data or len(response_data) < 10:
|
if not response_data or len(response_data) < 10:
|
||||||
if LogicOhli24.ensure_essential_dependencies():
|
if LogicOhli24.ensure_essential_dependencies():
|
||||||
|
import platform
|
||||||
|
is_mac = platform.system() == "Darwin"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
logger.debug(f"[Layer1] Trying Botasaurus @request: {url}")
|
if is_mac:
|
||||||
from botasaurus.request import request as b_request
|
# Mac에서는 gevent-Trio 충돌로 인해 서브프로세스로 실행
|
||||||
|
logger.debug(f"[Layer1] Trying Botasaurus subprocess (Mac workaround): {url}")
|
||||||
@b_request(headers=headers, use_stealth=True, proxy=LogicOhli24.get_proxy())
|
import subprocess
|
||||||
def fetch_url(request, data):
|
script_path = os.path.join(os.path.dirname(__file__), "lib", "botasaurus_ohli24.py")
|
||||||
return request.get(data)
|
|
||||||
|
cmd = [sys.executable, script_path, url, json.dumps(headers), LogicOhli24.get_proxy() or ""]
|
||||||
b_resp = fetch_url(url)
|
result = subprocess.run(
|
||||||
if b_resp and len(b_resp) > 10:
|
cmd,
|
||||||
logger.info(f"[Layer1] Botasaurus success, HTML len: {len(b_resp)}")
|
capture_output=True,
|
||||||
return b_resp
|
text=True,
|
||||||
|
timeout=timeout + 30
|
||||||
|
)
|
||||||
|
|
||||||
|
if result.returncode == 0 and result.stdout.strip():
|
||||||
|
b_result = json.loads(result.stdout.strip())
|
||||||
|
if b_result.get("success") and b_result.get("html"):
|
||||||
|
logger.info(f"[Layer1] Botasaurus(sub) success, HTML len: {len(b_result['html'])}")
|
||||||
|
return b_result["html"]
|
||||||
|
else:
|
||||||
|
logger.warning(f"[Layer1] Botasaurus(sub) failed: {b_result.get('error')}")
|
||||||
|
else:
|
||||||
|
logger.warning(f"[Layer1] Botasaurus subprocess error: {result.stderr}")
|
||||||
else:
|
else:
|
||||||
logger.warning(f"[Layer1] Botasaurus short response: {len(b_resp) if b_resp else 0}")
|
# Linux 등에서는 (monkey-patching 문제가 없다면) 직접 실행 시도
|
||||||
|
logger.debug(f"[Layer1] Trying Botasaurus @request (Direct): {url}")
|
||||||
|
from botasaurus.request import request as b_request
|
||||||
|
|
||||||
|
@b_request(headers=headers, use_stealth=True, proxy=LogicOhli24.get_proxy())
|
||||||
|
def fetch_url(request, data):
|
||||||
|
return request.get(data)
|
||||||
|
|
||||||
|
b_resp = fetch_url(url)
|
||||||
|
if b_resp and len(b_resp) > 10:
|
||||||
|
logger.info(f"[Layer1] Botasaurus success, HTML len: {len(b_resp)}")
|
||||||
|
return b_resp
|
||||||
|
else:
|
||||||
|
logger.warning(f"[Layer1] Botasaurus short response: {len(b_resp) if b_resp else 0}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"[Layer1] Botasaurus failed: {e}")
|
logger.warning(f"[Layer1] Botasaurus failed: {e}")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user