Download scripts/vision_ocr.py from FlanChanXwO/phpwind-captcha-ocr: direct link, hf CLI and curl.
- Browser
- Download file 1.89 kB
-
https://huggingface.co/FlanChanXwO/phpwind-captcha-ocr/resolve/main/scripts/vision_ocr.py
- Command line
-
hf download hf://FlanChanXwO/phpwind-captcha-ocr/scripts/vision_ocr.py
-
curl -L -o vision_ocr.py https://huggingface.co/FlanChanXwO/phpwind-captcha-ocr/resolve/main/scripts/vision_ocr.py
1.89 kB
| #!/usr/bin/env python3 | |
| """单图验证码识别,走 pie-xian command-a-vision。输出格式兼容 harness 的 recognize()。 | |
| 用法: vision_ocr.py file.png ... -> {"file.png": {"vision": "code"}} | |
| """ | |
| import base64 | |
| import json | |
| import re | |
| import ssl | |
| import sys | |
| import urllib.request | |
| API = "https://api.pie-xian.com/v1/chat/completions" | |
| KEY = "sk-Rel8iERHrmu9NDbvQhnhwTowEUnGqVvCFXMatASH8q5O4gGP" | |
| MODEL = "command-a-vision-07-2025" | |
| UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/126.0.0.0 Safari/537.36" | |
| PROMPT = "识别这张验证码图片中的字符。只输出字符本身,不要任何解释或标点。这是登录验证码,可能包含1-4个数字。" | |
| _CTX = ssl.create_default_context() | |
| _CTX.check_hostname = False | |
| _CTX.verify_mode = ssl.CERT_NONE | |
| def read(path): | |
| b64 = base64.b64encode(open(path, "rb").read()).decode() | |
| body = json.dumps({"model": MODEL, "messages": [{"role": "user", "content": [ | |
| {"type": "text", "text": PROMPT}, | |
| {"type": "image_url", "image_url": {"url": "data:image/png;base64," + b64}}]}], | |
| "max_tokens": 20, "temperature": 0}).encode() | |
| req = urllib.request.Request(API, data=body, headers={ | |
| "Authorization": "Bearer " + KEY, "Content-Type": "application/json", "User-Agent": UA}) | |
| d = json.loads(urllib.request.urlopen(req, timeout=90, context=_CTX).read()) | |
| return re.sub(r"[^0-9A-Za-z]", "", d["choices"][0]["message"]["content"]) | |
| def main(): | |
| out = {} | |
| for f in sys.argv[1:]: | |
| try: | |
| # 2 次读取,一致才返回;不一致返回空(harness 跳过登录) | |
| r1, r2 = read(f), read(f) | |
| code = r1 if r1 == r2 else "" | |
| out[f] = {"vision": code} | |
| except Exception as e: | |
| out[f] = {"vision": "", "err": str(e)} | |
| print(json.dumps(out, ensure_ascii=False)) | |
| if __name__ == "__main__": | |
| main() | |