Skip to content
This repository was archived by the owner on May 14, 2026. It is now read-only.

Commit cc55e9c

Browse files
committed
更新 .gitignore 文件以排除新的认证文件和临时数据目录;在 fetch_camoufox_data.py 中增强 SSL 证书验证的警告提示,新增用户确认步骤以提高安全性;在 server.py 中优化页面关闭逻辑,新增与 Camoufox 服务器的关闭信号功能,改进请求队列的关闭逻辑,提升用户体验和系统稳定性;在 README.md 中更新项目概述和核心特性,强调 Python 版本的优势和使用注意事项。
1 parent cda6b34 commit cc55e9c

10 files changed

Lines changed: 746 additions & 228 deletions

File tree

.gitignore

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,12 @@ __pycache__/
169169
errors_py/
170170

171171
# Authentication Profiles (Sensitive)
172-
auth_profiles/
172+
auth_profiles/active/
173+
auth_profiles/saved/
173174

174-
# Camoufox/Playwright Profile Data
175-
camoufox_profile/
175+
# Camoufox/Playwright Profile Data (Assume these are generated/temporary)
176+
camoufox_profile/
177+
chrome_temp_profile/
178+
179+
# Deprecated Javascript Version node_modules
180+
deprecated_javascript_version/node_modules/

README.md

Lines changed: 361 additions & 174 deletions
Large diffs are not rendered by default.

deprecated_javascript_version/README.md

Lines changed: 231 additions & 0 deletions
Large diffs are not rendered by default.

auto_connect_aistudio.cjs renamed to deprecated_javascript_version/auto_connect_aistudio.cjs

File renamed without changes.

package.json renamed to deprecated_javascript_version/package.json

File renamed without changes.

fetch_camoufox_data.py

Lines changed: 75 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,93 @@
11
import ssl
22
import sys
3-
# --- WARNING: Monkey patching SSL for fetching data ONLY ---
4-
# --- This disables certificate verification globally for this script execution ---
5-
# --- Do NOT use this approach for general network requests ---
6-
print("WARNING: Temporarily disabling SSL certificate verification to fetch Camoufox data...")
3+
import traceback
4+
5+
# --- WARNING: THIS SCRIPT DISABLES SSL VERIFICATION --- #
6+
# --- USE ONLY IF YOU TRUST YOUR NETWORK --- #
7+
# --- AND `camoufox fetch` FAILS DUE TO SSL --- #
8+
9+
print("="*60)
10+
print("WARNING: This script will temporarily disable SSL certificate verification")
11+
print(" globally for this Python process to attempt fetching Camoufox data.")
12+
print(" This can expose you to security risks like man-in-the-middle attacks.")
13+
print("="*60)
14+
15+
confirm = input("Do you understand the risks and want to proceed? (yes/NO): ").strip().lower()
16+
17+
if confirm != 'yes':
18+
print("Operation cancelled by user.")
19+
sys.exit(0)
20+
21+
print("\nAttempting to disable SSL verification...")
22+
original_ssl_context = None
723
try:
24+
# Store the original context creation function
25+
if hasattr(ssl, '_create_default_https_context'):
26+
original_ssl_context = ssl._create_default_https_context
27+
28+
# Get the unverified context creation function
829
_create_unverified_https_context = ssl._create_unverified_context
9-
except AttributeError:
10-
# Legacy Python versions might not have _create_unverified_context
11-
print("ERROR: Cannot disable SSL verification on this Python version.")
12-
sys.exit(1)
13-
else:
30+
1431
# Monkey patch the default context creation
1532
ssl._create_default_https_context = _create_unverified_https_context
16-
print("SSL verification temporarily disabled.")
33+
print("SSL verification temporarily disabled for this process.")
34+
except AttributeError:
35+
print("ERROR: Cannot disable SSL verification on this Python version (missing necessary SSL functions).")
36+
sys.exit(1)
37+
except Exception as e:
38+
print(f"ERROR: An unexpected error occurred while trying to disable SSL verification: {e}")
39+
traceback.print_exc()
40+
sys.exit(1)
1741

1842
# Now, try to import and run the fetch command logic from camoufox
19-
print("Attempting to run Camoufox fetch logic...")
43+
print("\nAttempting to run Camoufox fetch logic...")
44+
fetch_success = False
2045
try:
2146
# The exact way to trigger fetch programmatically might differ.
2247
# This tries to import the CLI module and run the fetch command.
2348
from camoufox import cli
2449
# Simulate command line arguments: ['fetch']
25-
cli.cli(['fetch'])
26-
print("Camoufox fetch process finished.")
50+
# Note: cli.cli() might exit the process directly on completion or error.
51+
# We assume it might raise an exception or return normally.
52+
cli.cli(['fetch'])
53+
print("Camoufox fetch process seems to have completed.")
54+
# We assume success if no exception was raised and the process didn't exit.
55+
# A more robust check would involve verifying the downloaded files,
56+
# but that's beyond the scope of this simple script.
57+
fetch_success = True
2758
except ImportError:
28-
print("\nERROR: Could not import camoufox.cli. Make sure camoufox package was installed (even partially).")
29-
print("Try running: python3 -m pip list | grep camoufox")
59+
print("\nERROR: Could not import camoufox.cli. Make sure camoufox package is installed.")
60+
print(" Try running: pip show camoufox")
3061
except FileNotFoundError as e:
31-
print(f"\nERROR during fetch (likely download failed again despite disabled SSL?): {e}")
32-
print("Please check network connectivity and permissions.")
62+
print(f"\nERROR during fetch (FileNotFoundError): {e}")
63+
print(" This might indicate issues with file paths or permissions during download/extraction.")
64+
print(" Please check network connectivity and directory write permissions.")
65+
except SystemExit as e:
66+
# The CLI might use sys.exit(). We interpret non-zero exit codes as failure.
67+
if e.code == 0:
68+
print("Camoufox fetch process exited successfully (code 0).")
69+
fetch_success = True
70+
else:
71+
print(f"\nERROR: Camoufox fetch process exited with error code: {e.code}")
3372
except Exception as e:
34-
print(f"\nERROR running camoufox fetch programmatically: {e}")
35-
import traceback
73+
print(f"\nERROR: An unexpected error occurred while running camoufox fetch: {e}")
3674
traceback.print_exc()
75+
finally:
76+
# Attempt to restore the original SSL context
77+
if original_ssl_context:
78+
try:
79+
ssl._create_default_https_context = original_ssl_context
80+
print("\nOriginal SSL context restored.")
81+
except Exception as restore_e:
82+
print(f"\nWarning: Failed to restore original SSL context: {restore_e}")
83+
else:
84+
# If we couldn't store the original, we can't restore it.
85+
# The effect was process-local anyway.
86+
pass
87+
88+
if fetch_success:
89+
print("\nFetch attempt finished. Please verify if Camoufox browser files were downloaded successfully.")
90+
else:
91+
print("\nFetch attempt failed or exited with an error.")
3792

38-
print("Script finished. SSL verification will be enabled again on next Python run.")
93+
print("Script finished.")

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
fastapi
22
uvicorn[standard]
33
playwright
4-
camoufox
5-
browserforge
4+
camoufox[geoip]
5+
pydantic

server.py

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -660,13 +660,41 @@ async def _initialize_page_logic(browser: AsyncBrowser):
660660

661661
# --- Page Shutdown Logic --- (Translate print statements)
662662
async def _close_page_logic():
663-
# ... (code unchanged) ...
664663
global page_instance, is_page_ready
665664
print("--- 运行页面逻辑关闭 --- ") # 中文
665+
if page_instance:
666+
if not page_instance.is_closed():
667+
try:
668+
await page_instance.close()
669+
print(" ✅ 页面已关闭")
670+
except Exception as e:
671+
print(f" ⚠️ 关闭页面时出错: {e}")
672+
else:
673+
print(" ℹ️ 页面已处于关闭状态")
674+
else:
675+
print(" ℹ️ 页面实例不存在")
666676
page_instance = None
667677
is_page_ready = False
668678
print("页面逻辑状态已重置。") # 中文
669679

680+
# --- 新增:与Camoufox服务器通信的关闭信号函数 ---
681+
async def signal_camoufox_shutdown():
682+
"""通知 Camoufox 服务器准备关闭"""
683+
try:
684+
print(" 发送关闭信号到 Camoufox 服务器...")
685+
# 检查ws_endpoint环境变量是否存在
686+
ws_endpoint = os.environ.get('CAMOUFOX_WS_ENDPOINT')
687+
if not ws_endpoint:
688+
print(" ⚠️ 无法发送关闭信号:未找到 CAMOUFOX_WS_ENDPOINT 环境变量")
689+
return
690+
691+
# 这里可以实现实际的通信逻辑,例如通过 WebSocket 发送关闭命令
692+
# 由于目前没有直接的通信机制,我们添加一个短暂延迟,让服务器有时间准备
693+
await asyncio.sleep(0.5) # 给服务器一点反应时间
694+
print(" ✅ 关闭信号已发送")
695+
except Exception as e:
696+
print(f" ⚠️ 发送关闭信号失败: {e}")
697+
670698
# --- Lifespan context manager ---
671699
@asynccontextmanager
672700
async def lifespan(app_param: FastAPI):
@@ -746,49 +774,61 @@ async def lifespan(app_param: FastAPI):
746774

747775
print(f"\\nFastAPI 生命周期: 关闭中...") # 中文
748776

749-
# !! 新增:关闭队列 Worker !!
777+
# !! 优化:改进队列 Worker 关闭逻辑 !!
750778
if worker_task and not worker_task.done():
751779
print(f" 正在取消请求队列 Worker...") # 中文
752780
worker_task.cancel()
753781
try:
754-
await worker_task # Wait for the worker to finish cancellation
782+
# 增加超时防止无限等待
783+
await asyncio.wait_for(worker_task, timeout=5.0)
755784
print(f" ✅ 请求队列 Worker 已停止。") # 中文
785+
except asyncio.TimeoutError:
786+
print(f" ⚠️ Worker 等待超时,继续关闭流程。")
756787
except asyncio.CancelledError:
757788
print(f" ✅ 请求队列 Worker 已确认取消。") # 中文
758789
except Exception as wt_err:
759790
print(f" ❌ 等待 Worker 停止时出错: {wt_err}") # 中文
760791
else:
761-
print(f" ⚠️ Worker 任务未运行或已完成。") # 中文
792+
print(f" ℹ️ Worker 任务未运行或已完成。") # 中文
793+
794+
# 发送关闭信号到 Camoufox 服务器
795+
await signal_camoufox_shutdown()
762796

797+
# 关闭页面
763798
await _close_page_logic() # Existing page close logic
764799

765-
if browser_instance and browser_instance.is_connected():
766-
print(f" 正在关闭与浏览器实例的连接...") # 中文
767-
try:
768-
await browser_instance.close()
769-
print(f" ✅ 浏览器连接已关闭。") # 中文
770-
except Exception as close_err:
771-
print(f" ❌ 关闭浏览器连接时出错: {close_err}") # 中文
772-
finally:
773-
browser_instance = None
774-
is_browser_connected = False
775-
else:
776-
print(f" ⚠️ 未找到活动的浏览器连接以关闭。") # 中文
800+
# 改进浏览器连接关闭逻辑
801+
if browser_instance:
802+
print(f" 正在关闭与浏览器实例的连接...") # 中文
803+
try:
804+
if browser_instance.is_connected():
805+
await browser_instance.close()
806+
print(f" ✅ 浏览器连接已关闭。") # 中文
807+
else:
808+
print(f" ℹ️ 浏览器已断开连接,无需关闭。")
809+
except Exception as close_err:
810+
print(f" ❌ 关闭浏览器连接时出错: {close_err}") # 中文
811+
finally:
812+
browser_instance = None
813+
is_browser_connected = False
814+
else:
815+
print(f" ℹ️ 浏览器实例不存在。") # 中文
777816

778-
if playwright_manager:
779-
print(f" 停止 Playwright...") # 中文
780-
try:
781-
await playwright_manager.stop()
782-
print(f" ✅ Playwright 已停止。") # 中文
783-
except Exception as stop_err:
784-
print(f" ❌ 停止 Playwright 时出错: {stop_err}") # 中文
785-
finally:
786-
playwright_manager = None
787-
is_playwright_ready = False
788-
else:
789-
print(f" ⚠️ 未找到 Playwright 管理器。") # 中文
817+
# 关闭 Playwright
818+
if playwright_manager:
819+
print(f" 停止 Playwright...") # 中文
820+
try:
821+
await playwright_manager.stop()
822+
print(f" ✅ Playwright 已停止。") # 中文
823+
except Exception as stop_err:
824+
print(f" ❌ 停止 Playwright 时出错: {stop_err}") # 中文
825+
finally:
826+
playwright_manager = None
827+
is_playwright_ready = False
828+
else:
829+
print(f" ℹ️ Playwright 管理器不存在。") # 中文
790830

791-
print(f"✅ FastAPI 生命周期: 关闭完成。") # 中文
831+
print(f"✅ FastAPI 生命周期: 关闭完成。") # 中文
792832

793833

794834
# --- FastAPI App ---

0 commit comments

Comments
 (0)