| |
| """单图验证码识别,走 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: |
| |
| 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() |
|
|