diff --git a/README.md b/README.md index 13ad2a9e80..c5ffb00b7d 100644 --- a/README.md +++ b/README.md @@ -66,9 +66,6 @@ Just implement some interfaces to make `AI vs AI` possible. ```bash # hcaptcha-challenger/src python main.py demo - - # Linux. - export LANGUAGE=zh_CN.UTF8 && python3 main.py demo ``` ## Advanced diff --git a/src/apis/scaffold/challenge.py b/src/apis/scaffold/challenge.py index 60376e90f7..c87431290e 100644 --- a/src/apis/scaffold/challenge.py +++ b/src/apis/scaffold/challenge.py @@ -10,12 +10,14 @@ from services.settings import logger, HCAPTCHA_DEMO_SITES, DIR_MODEL, DIR_CHALLENGE from services.utils import get_challenge_ctx +SAMPLE_SITE = HCAPTCHA_DEMO_SITES[0] -def demo(silence: Optional[bool] = False, onnx_prefix="yolov5s6"): + +def demo(silence: Optional[bool] = False, onnx_prefix: Optional[str] = None): """人机挑战演示 顶级接口""" logger.info("Starting demo project...") - # 指定嵌入式模型 + # 实例化嵌入式模型 yolo = YOLO(DIR_MODEL, onnx_prefix=onnx_prefix) # 实例化挑战者组件 @@ -26,15 +28,14 @@ def demo(silence: Optional[bool] = False, onnx_prefix="yolov5s6"): ctx = get_challenge_ctx(silence=silence) try: # 读取 hCaptcha challenge 测试站点 - # 默认使用 maximedrn 提供的测试站点 - demo_url = HCAPTCHA_DEMO_SITES[0] - ctx.get(demo_url) + ctx.get(SAMPLE_SITE) + # 必要的等待时间 time.sleep(3) - # 检测当前页面是否出现可点击的 hcaptcha checkbox - # 测试站点必然会弹出 checkbox,此处的弹性等待时长默认为 5s, - # 若 5s 仍未加载出 checkbox 说明您当前的网络状态堪忧 + # 检测当前页面是否出现可点击的 `hcaptcha checkbox` + # `样本站点` 必然会弹出 `checkbox`,此处的弹性等待时长默认为 5s, + # 若 5s 仍未加载出 `checkbox` 说明您当前的网络状态堪忧 if challenger_utils.face_the_checkbox(ctx): start = time.time() @@ -56,12 +57,8 @@ def test(): """检查挑战者驱动版本是否适配""" ctx = get_challenge_ctx(silence=True) try: - ctx.get("https://www.baidu.com") + ctx.get(SAMPLE_SITE) finally: ctx.quit() logger.success("The adaptation is successful") - - -if __name__ == '__main__': - demo() diff --git a/src/apis/scaffold/install.py b/src/apis/scaffold/install.py index 07c52ff427..601d10022c 100644 --- a/src/apis/scaffold/install.py +++ b/src/apis/scaffold/install.py @@ -5,6 +5,7 @@ # Description: import sys import webbrowser +from typing import Optional from webdriver_manager.utils import get_browser_version_from_os @@ -12,7 +13,7 @@ from services.settings import DIR_MODEL, logger -def _download_model(onnx_prefix="yolov5s6"): +def _download_model(onnx_prefix: Optional[str] = None): """下载 YOLOv4 目标检测模型""" logger.debug("Downloading YOLOv5 object detection model...") @@ -47,7 +48,7 @@ def _download_driver(): ) -def run(model: str = "yolov5s6"): +def run(model: Optional[str] = None): """下载项目运行所需的各项依赖""" _download_model(onnx_prefix=model) _download_driver() diff --git a/src/main.py b/src/main.py index 0df74f6913..285e961961 100644 --- a/src/main.py +++ b/src/main.py @@ -2,7 +2,7 @@ # Time : 2022/2/15 17:40 # Author : QIN2DIM # Github : https://github.com/QIN2DIM -# Description: 🚀 哟挑战者! +# Description: 🚀 Yo Challenger! from fire import Fire from services.scaffold import Scaffold diff --git a/src/services/hcaptcha_challenger/core.py b/src/services/hcaptcha_challenger/core.py index 225c71afa4..0cbd4d8a4d 100644 --- a/src/services/hcaptcha_challenger/core.py +++ b/src/services/hcaptcha_challenger/core.py @@ -30,7 +30,7 @@ class YOLO: - """用于实现图像分类的 YOLO 模型""" + """YOLO model for image classification""" def __init__(self, dir_model, onnx_prefix: str = "yolov5s6"): self.dir_model = "./model" if dir_model is None else dir_model @@ -131,7 +131,7 @@ def __init__(self, dir_model, onnx_prefix: str = "yolov5s6"): ] def download_model(self): - """下载模型和权重参数""" + """Download model and weight parameters""" if not os.path.exists(self.dir_model): os.mkdir(self.dir_model) if os.path.exists(self.onnx_model["path"]): @@ -143,10 +143,14 @@ def download_model(self): def detect_common_objects(self, img_stream, confidence=0.4, nms_thresh=0.4): """ - 目标检测 + Object Detection - 获取给定图像中识别出的多个标签 - :param img_stream: 图像文件二进制流 + Get multiple labels identified in a given image + + :param img_stream: image file binary stream + with open(img_filepath, "rb") as file: + data = file.read() + detect_common_objects(img_stream=data) :param confidence: :param nms_thresh: :return: bbox, label, conf @@ -192,7 +196,7 @@ def detect_common_objects(self, img_stream, confidence=0.4, nms_thresh=0.4): class ArmorCaptcha: - """hCAPTCHA challenge 驱动控制""" + """hCAPTCHA challenge drive control""" def __init__(self, dir_workspace: str = None, debug=False): @@ -209,6 +213,7 @@ def __init__(self, dir_workspace: str = None, debug=False): "卡车": "truck", "公交车": "bus", "巴土": "bus", + "巴士": "bus", "飞机": "aeroplane", "ー条船": "boat", "船": "boat", @@ -216,11 +221,11 @@ def __init__(self, dir_workspace: str = None, debug=False): "摩托车": "motorbike", } - # 样本标签映射 {挑战图片1: locator1, ...} + # Store the `element locator` of challenge images {挑战图片1: locator1, ...} self.alias2locator = {} - # 填充下载链接映射 {挑战图片1: url1, ...} + # Store the `download link` of the challenge image {挑战图片1: url1, ...} self.alias2url = {} - # 填充挑战图片的缓存地址 {挑战图片1: "/images/挑战图片1.png", ...} + # Store the `directory` of challenge image {挑战图片1: "/images/挑战图片1.png", ...} self.alias2path = {} # 存储模型分类结果 {挑战图片1: bool, ...} self.alias2answer = {} diff --git a/src/services/scaffold.py b/src/services/scaffold.py index 519229f231..913f50bb15 100644 --- a/src/services/scaffold.py +++ b/src/services/scaffold.py @@ -9,19 +9,19 @@ class Scaffold: - """系统脚手架 顶级接口指令""" + """System scaffolding Top-level interface commands""" @staticmethod - def install(model:Optional[str]="yolov5s6"): - """下载运行依赖""" + def install(model: Optional[str] = None): + """Download Project Dependencies""" install.run(model=model) @staticmethod def test(): - """测试挑战者驱动是否适配""" + """Test the Challenger drive for fitment""" challenge.test() @staticmethod - def demo(silence: Optional[bool] = False, model: Optional[str] = "yolov5s6"): - """正面硬刚人机挑战""" + def demo(silence: Optional[bool] = False, model: Optional[str] = None): + """Dueling with hCaptcha challenge""" challenge.demo(silence=silence, onnx_prefix=model) diff --git a/src/services/settings.py b/src/services/settings.py index 0c5739e895..86c3496b1e 100644 --- a/src/services/settings.py +++ b/src/services/settings.py @@ -12,28 +12,33 @@ "https://maximedrn.github.io/hcaptcha-solver-python-selenium/" ] # --------------------------------------------------- -# [√]工程根目录定位 +# [√]Lock the project directory # --------------------------------------------------- -# 系统根目录 +# Source root directory PROJECT_ROOT = dirname(dirname(__file__)) -# 文件数据库目录 + +# File database directory PROJECT_DATABASE = join(PROJECT_ROOT, "database") -# YOLO模型 + +# The storage directory of the YOLO object detection model DIR_MODEL = join(PROJECT_ROOT, "model") -# 运行缓存目录 + +# Run cache directory DIR_TEMP_CACHE = join(PROJECT_DATABASE, "temp_cache") -# 挑战缓存 + +# Directory for challenge images DIR_CHALLENGE = join(DIR_TEMP_CACHE, "_challenge") -# 服务日志目录 + +# Service log directory DIR_LOG = join(PROJECT_DATABASE, "logs") # --------------------------------------------------- -# [√]服务器日志配置 +# [√]Server log configuration # --------------------------------------------------- logger = ToolBox.init_log( error=join(DIR_LOG, "error.log"), runtime=join(DIR_LOG, "runtime.log") ) # --------------------------------------------------- -# 路径补全 +# [√]Path completion # --------------------------------------------------- for _pending in [ PROJECT_DATABASE, diff --git a/src/services/utils/toolbox/toolbox.py b/src/services/utils/toolbox/toolbox.py index d6fee5a880..665bdc194c 100644 --- a/src/services/utils/toolbox/toolbox.py +++ b/src/services/utils/toolbox/toolbox.py @@ -3,6 +3,7 @@ # Author : QIN2DIM # Github : https://github.com/QIN2DIM # Description: +import os import sys from typing import Optional @@ -12,11 +13,11 @@ class ToolBox: - """可移植的工具箱""" + """Portable Toolbox""" @staticmethod def init_log(**sink_path): - """初始化 loguru 日志信息""" + """Initialize loguru log information""" event_logger_format = ( "{time:YYYY-MM-DD HH:mm:ss} | " "{level} - " @@ -51,20 +52,31 @@ def init_log(**sink_path): return logger -def _set_ctx() -> ChromeOptions: - """统一的 ChromeOptions 启动参数""" - options = ChromeOptions() - options.add_argument("--log-level=3") - options.add_argument("--lang=zh-CN") # 可能仅在 Windows 生效 - options.add_argument("--disable-dev-shm-usage") - return options +def get_challenge_ctx(silence: Optional[bool] = None, language: Optional[str] = None): + """ + Challenger drive for handling human-machine challenges + :param silence: Control headless browser -def get_challenge_ctx(silence: Optional[bool] = None): - """挑战者驱动 用于处理人机挑战""" + :param language: Restrict the language of hCatpcha label. + In the current version, `language` parameter must be `zh`. + See https://github.com/QIN2DIM/hcaptcha-challenger/issues/2 + :return: + """ + # Control headless browser silence = True if silence is None or "linux" in sys.platform else silence - # 控制挑战者驱动版本,避免过于超前 + # - Restrict browser startup parameters + options = ChromeOptions() + options.add_argument("--log-level=3") + options.add_argument("--disable-dev-shm-usage") + + # - Restrict the language of hCaptcha label + # - Environment variables are valid only in the current process + # and do not affect other processes in the operating system + os.environ["LANGUAGE"] = "zh" if language is None else language + options.add_argument(f"--lang={os.getenv('LANGUAGE')}") + logger.debug("🎮 Activate challenger context") - return uc.Chrome(options=_set_ctx(), headless=silence) + return uc.Chrome(options=options, headless=silence)