Scarnox · Blog

Bild- und Text-Captcha per OCR lesen: verzerrte Captchas auslesen

Ein Bild-Captcha zeigt eine kurze Zeichenfolge aus Buchstaben oder Ziffern als Bild, manchmal mit Rauschen, Drehung und welligen Linien. Optische Zeichenerkennung (OCR) kann einfache Varianten davon mit einer Open-Source-Engine wie Tesseract lesen. Die Genauigkeit hängt davon ab, wie sauber das Bild ist, deshalb steckt der größte Teil der Arbeit in der Vorverarbeitung. Dieser Leitfaden zeigt ein funktionierendes Python-Setup, erklärt, wo es scheitert, und stellt eines klar: Die Live-API von Scarnox löst PopularCaptcha-Widget-Tokens, nicht Bild-zu-Text-Captchas. Plane OCR als deinen eigenen Code ein, nicht als API-Aufruf.

Wann OCR funktioniert und wann nicht

OCR ist ein vernünftiger erster Versuch, wenn der Text

Schwierigkeiten hat sie mit gedrehten Buchstaben, sich berührenden Buchstaben, Hintergrundmustern und Linien, die durch die Glyphen gezogen sind. Jede dieser Störungen braucht einen eigenen Vorverarbeitungsschritt, und manche brauchen ein ganz anderes Modell. Sei bereit, die Genauigkeit zu messen, statt sie vorauszusetzen.

Werkzeuge installieren

Du brauchst Python, das Tesseract-Programm und zwei Python-Pakete:

pip install pillow pytesseract

Tesseract selbst ist eine separate Installation. Unter Windows verwendest du den Installer des Tesseract-Projekts und sorgst dafür, dass die ausführbare Datei im PATH liegt, oder du setzt pytesseract.pytesseract.tesseract_cmd auf ihren Pfad.

Vorverarbeiten, dann lesen

Der größte Teil der Genauigkeit kommt von sauberer Eingabe. Die folgende Sequenz wandelt in Graustufen um, erhöht den Kontrast, wendet einen harten Schwellenwert an, skaliert das Bild hoch und beschränkt die Ausgabe auf die Zeichen, die das Captcha verwendet:

from PIL import Image, ImageOps
import pytesseract

# Zeichen, die das Captcha verwenden kann. Lass Verwechslungsgefahr wie 0/O und 1/I weg,
# wenn das Captcha diese nie verwendet.
ALLOWED = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789"

def read_text(path: str) -> str:
    img = Image.open(path)
    gray = ImageOps.grayscale(img)
    gray = ImageOps.autocontrast(gray)
    # Harter Schwellenwert: Pixel heller als 140 werden weiß, der Rest schwarz.
    bw = gray.point(lambda p: 255 if p > 140 else 0)
    # Tesseract arbeitet besser mit größeren Glyphen.
    bw = bw.resize((bw.width * 3, bw.height * 3))
    config = f"--psm 7 -c tessedit_char_whitelist={ALLOWED}"  # psm 7: eine Textzeile
    return pytesseract.image_to_string(bw, config=config).strip()

if __name__ == "__main__":
    print(read_text("sample_captcha.png"))

Der Schwellenwert 140 ist ein Ausgangspunkt. Gib das verarbeitete Bild aus, vergleiche es mit dem Original und passe den Wert an, bis die Buchstaben voll und der Hintergrund sauber sind.

Genauigkeit messen, bevor du dich darauf verlässt

Ein korrektes Ergebnis bei einem einzelnen Bild beweist nichts. Speichere eine Reihe von Captchas mit bekannten Antworten, führe die Funktion auf allen aus und zähle die Treffer:

def accuracy(samples: dict[str, str]) -> float:
    # samples bildet einen Dateipfad auf den richtigen Text ab
    hits = sum(read_text(path) == truth for path, truth in samples.items())
    return hits / len(samples)

labelled = {
    "samples/0001.png": "K7PQ2",
    "samples/0002.png": "M3XN9",
}
print(f"accuracy: {accuracy(labelled):.0%}")

Verfolge diese Zahl jedes Mal, wenn du die Vorverarbeitung änderst. Wenn der Wert nach mehreren Änderungen niedrig bleibt, ist OCR wahrscheinlich das falsche Werkzeug für diesen Captcha-Stil, und du solltest einen anderen Ansatz prüfen.

Wo es scheitert

Eine Checkliste zur Vorverarbeitung

Wenn ein Lesevorgang fehlschlägt, arbeite diese Punkte der Reihe nach ab. Ändere jeweils nur eine Sache, damit du siehst, welcher Schritt geholfen hat:

  1. Prüfe die Eingabegröße. Sehr kleine Captchas werden nach einer 3-fachen Vergrößerung oft besser gelesen.
  2. Wandle in Graustufen um und dehne den Kontrast, damit sich die Buchstaben abheben.
  3. Wende einen Schwellenwert an und probiere ein paar Werte, bevor du dich festlegst.
  4. Entferne Sprenkelrauschen mit einem Medianfilter und setze den Schwellenwert bei Bedarf erneut an.
  5. Schneide das Bild auf den Textbereich zu, damit der Hintergrund die Engine nicht verwirrt.
  6. Beschränke den Zeichensatz auf den, den das Captcha verwendet.
  7. Probiere einen anderen Seitensegmentierungsmodus, wenn der Text verteilt oder gestapelt ist.

Halte Reihenfolge und Einstellungen zusammen mit deinen beschrifteten Beispielen in der Versionsverwaltung. Eine Vorverarbeitungs-Pipeline ist Code und sollte auch wie Code geprüft werden.

OCR oder ein Modell, das du selbst betreibst

Klassisches OCR ist schnell und läuft auf einem Laptop, bricht aber, sobald ein Captcha seinen Stil ändert. Bildmodelle, die auf deiner eigenen beschrifteten Menge trainiert wurden, kommen mit mehr Variation zurecht, verlangen dafür aber das Sammeln von Daten und das Ausführen der Inferenz. Beides musst du selbst aufbauen und pflegen. Keines davon ist derzeit ein gehosteter Scarnox-Endpunkt, also plane die Infrastruktur, bevor du dich für eines entscheidest.

Was Scarnox hier tut und was nicht

Die Live-API von Scarnox löst PopularCaptcha-Widget-Tokens. Die Anfrage ist POST https://api.scarnox.com/api/tasks/create mit einem PopularCaptcha-Task-Typ, einem Sitekey und einer Seiten-URL, und die Antwort ist ein Token für das Formularfeld. Das ist eine andere Aufgabe als das Lesen von Text in einem Bild. Scarnox bietet heute keinen Bild-zu-Text-Endpunkt. Wenn dein Problem ein Bild-Captcha ist, nutze OCR oder ein Modell, das du selbst betreibst, und lies die anderen Leitfäden, um zu sehen, was Scarnox abdeckt. Du kannst ein Konto erstellen und mit kostenlosem Testguthaben starten, ohne Karte, für die PopularCaptcha-Abläufe, die unterstützt werden. Die aktuellen Preise stehen auf der Preisseite.

Legitime Einsatzzwecke

Verwende OCR nicht, um ein Captcha auf einer Seite zu umgehen, die automatisierten Zugriff nicht erlaubt. Bild-Captchas existieren genau dafür, solches Vorgehen zu bremsen.

Nächste Schritte