Pentru cine nu știe, Sikuli probabil a luat naștere undeva prin anul 2010, și este în principal o librărie Java pentru recunoaștere de imagini. Dar totodată este și un set de mini programe ce pot utiliza un limbaj scripting în cazul în care nu folosim librăria jar într-un proiect Java.
Acum jumătate de an sau mai bine l-am încercat pentru a experimenta cât de bine poate fi folosit pentru a valida verificări cu imagini Captcha. Nu de alta dar încă mai există mulți chinezi sau indonezieni care introduc 500Captcha/1$, evident ca multe dintre acele imagini care sunt introduse sunt pentru serviciile Google sau Facebook și în alte locuri unde Spam-ul este valorificat și sunt imagini a căror posibilitate de validare print-un mod programatic este continuu evaluată și redusă la 0 prin modificarea algoritmului de rendare a Captcha-ului. Îmi amintesc de știrea virală care s-a declanșat când reCaptcha putea fi validat automat printr-un algoritm de recunoaștere audio, dat fiind faptul ca autorul a explicat totul a fost foarte ușor numai în decurs de o zi ca sunetul de validare sa fie astfel reprodus încât să nu mai existe această vulnerabilitate.
Totuși cu recunoaștere de imagini și cu un algoritm de similaritate între două imagini nu ai cum nicicând să validezi un reCaptcha, pentru reCaptcha poate ai putea( dacă nu ai ce face și probabil cu rezultate precare ) sa iți încerci norocul cu "Pattern Recognition".
În orice caz acele captcha-uri care nu pot fi validate programatic sunt destul de enervante și pentru semeni noștri și sunt destule servicii/siteuri care folosesc captcha-uri mai simple, cum sunt spre exemplu acele captcha-uri care te pun sa alegi dintr-un set de imagini, imaginea care este reprezentata ca forma alterata a uneia dintre imaginile din set. Și aici intervine posibilitatea unde am putea utiliza o funcție de similaritate(Sikulix), care va reda un procent de similaritate determinat de librărie.
Sincer nu am experimentat mult cu SikuliX și probabil acel limbaj scripting de care se folosește SikuliX este python judecând după sintaxă, ce mi s-a părut neplăcut a fost ca la preluarea unui Map(x,y) de pixeli nu puteai sa lucrezi cu el în memorie lucru care afectează viteza, și posibilitățile de a intervenii prea mult în ceea ce se întâmplă în spate prin parametri erau minime.
În orice caz am reușit să scriu un script care să și facă treaba cu o rată mică de eroare, acum nu o sa spun pe ce serviciu l-am testat dar o sa pun codul mai jos:
[sourcecode language="python"]
import time
import os
from org.sikuli.basics.proxies import Vision
def eH(gresit,count):
if count == 5:
return
if count is None:
count = 0
if gresit is None:
gresit = []
# Linie Debug
#popup(str(gresit))
# Reglare calitate recunoastere ( setat 6 pt viteza mai mare acuratete mai slaba)
#Vision.setParameter("MinTargetSize", 6)
#identificare locatie captcha ( aceleasi coordonate )
# pun in variabila coordonatele pt ca altfel ide-ul imi arata regiunea ca imagine .
rCoor = [14,105,276,55]
AReg = Region(rCoor[0],rCoor[1],rCoor[2],rCoor[3])
# Impartim captcha in 5 regiuni mai mici
img = []
img.append(Region(AReg.getX()+1,AReg.getY()+1, 54, 54))
img.append(Region(AReg.getX()+1+55,AReg.getY()+1, 54, 54))
img.append(Region(AReg.getX()+1+55+55,AReg.getY()+1, 54, 54))
img.append(Region(AReg.getX()+1+55+55*2,AReg.getY()+1, 54, 54))
img.append(Region(AReg.getX()+1+55+55*3,AReg.getY()+1, 54, 54))
# Prosteala cu +55 blabla bla evident ....
# Capturam Imaginile ( dezamagitor ca nu suporta capturare in memorie )
Scr = Screen()
cap = []
cap.append(Scr.capture(img[0]))
cap.append(Scr.capture(img[1]))
cap.append(Scr.capture(img[2]))
cap.append(Scr.capture(img[3]))
cap.append(Scr.capture(img[4]))
# Variabile pt identificarea imaginii similare
pmax = 0
max = 0
found = 0
# unele limbaje au operator special pentru a oprii un loop la un anumit nivel
# python nu are, in concluzie folosim un flag like old days
bOuterLoop = 0
if len(gresit) > 0:
founda = gresit
else:
founda = []
imgf = ""
# Nu vrem exceptii in caz de neidentificare a similaritatii
for x in range(0,4):
img[x].setThrowException(False)
# for for for ...
for x in range(0, 4):
for y in range(0,4):
if x == y:
continue
if (len(founda) > 0):
for x in range(0,len(founda)):
if x == found:
bOuterLoop = 1
if bOuterLoop == 1:
bOuterLoop = 0
continue
aM = img[x].find(Pattern(cap[y]).similar(0.2))
if (aM is None):
continue
else:
max = aM.getScore()
if pmax <= max:
pmax = max
imgf = img[x]
found = x
# mai stergem si noi ceva
for x in range(0,4):
os.remove(cap[x])
# Am gasit ceva sau nu ?
if isinstance(imgf, Region):
click(imgf)
hover(Region(0,0,4,4))
rNewCoor = [70,101,157,36]
regNewSeeError = Region( rNewCoor[0],rNewCoor[1],rNewCoor[2],rNewCoor[3])
regNewSeeError.setThrowException(False)
# Find this baby one more time
allwaysFindShoudHappen = regNewSeeError.find("wrgc.png")
# Asta nu ar trebui niciodata in circumstantele normale asa ca nu mai tratez exceptia, let it happen ...
if not (allwaysFindShoudHappen is None):
gresit.append(found)
time.sleep(20)
eH(gresit,count+1)
time.sleep(10)
# 5 recursii fara for intr-un loop spre infinit se indreapta in mod grabit catre totul sau nimic
test = eH([],0)
#popup(str(pmax))
[/sourcecode]
Totuși proiectul SikuliX pare cam mort cu toate ca se anunță o rescriere a versiunii 2 care ar fi trebuit să înceapă în ianuarie 2015, sunt chiar curios dacă va mai reuși să trezească vreun interes.