灌水脚本--基于LAScript

答应某人做个QQ空间自动灌水的脚本
基本上的功能都有了,可惜还是差了一点点,一直都没有拿出来。
QQ验证码的样本实在太多,该死的图片比较又不是很聪明,4个图片往往只能辨别出2,3个,甚至一个都认不出来。有空的时候自己去写个图片识别的来

不管怎样,还是先把这些脚本给整理出来了,期待有朝一日出来新的图片比较API,让该死的QQ验证码见鬼去吧

----------------------------------------------------获取图片-----------------------------------------------------------------------
getImg= function()
local ele=wb:getEle("temp");--这是模拟程序web界面上的一个节点,用来显示程序运行过程的相关信息
tab={wb:eleImages()}; --枚举web页所有图片

img=image.new();
for i,tele in ipairs(tab) do
  if tele:id()=='idtimage' then --获取指定id的图片
   tele:exec("Copy");  --拷贝
   img:getClipBD() ;--从粘贴板获取
  end
end;
img:Crop(1,2,37,18);--修剪图片。查看下载下来的图片,不断微调。 每个验证码图片这个参数可能不同。
img2,img3,img4,img5=img:split(1,4);  --分割图片

img:paint(100,100,40,20);  --屏幕显示图片
img2:paint(100,120,10,20);
img3:paint(120,120,10,20);
img4:paint(140,120,10,20);
img5:paint(160,120,10,20);
img:save("c:\\temp\\temp.png");--把图片保存到本地
ele:setAttribute("value","已从指定网址得到图像");--在web界面上显示提示信息。
ele:setAttribute("value","拆分并保存图像已经完成");--在web界面上显示提示信息
return img;
end;

------------------------------得到样本图片并保存在数据岛的函数------------------------------------------------------------------
sampleImg=function()
--遍历图片目录,读取样本图片
local tkey={};
win.enumProc = function(dir,filename)
  if(not dir)then
   tkey[string.sub(filename,9,10)]=string.sub(filename,9,14);  --文件名形如c:\test\1a.jpg
     end;
  return nStop();
end;
win.enumDir("c:\\test\\","*.jpg")  --显示该目录*.jpg文件
--k参数为键,v参数表示值 一个典型的tkeyle迭代器回调函数
loadtkey = function(k,v)
     local img = image.new();
     img:load("C:\\test\\"..k..".jpg");
     assert(img:ok(),"C:\\test\\"..k..".jpg".."\n不是有效的图片");
    
     img:bpp(1);
  img:bpp(24);
     --通过上面两句,轻松去掉验证码上的杂色杂点
    
     img:Crop( 0 , 0 , 9 , 16);--修剪单个字符
     img:median(2);--中值滤波进一步去杂点
    
     tkey[k]= string.encode( img:getBytes("*.jpg") , "");
     --因为转换到字符串还是二进制,所以用base64进行编码
     image.del(img);
end;

--遍历表tkey的所有元素,调用loadtkey加载图片文件
for k,v in pairs(tkey) do
     loadtkey(k,v);
end;

--把所有图片保存到数据岛,
ape:saveTable(tkey,"验证码样本")
end;
----------------------------------------------把界面写入web窗体的函数-------------------------------------------------------
write= function()
html = [[
<html>
<head>
<meta http-equiv="Content-Type" c>
<title>form</title>
</head>
<script> LAScript=external;;</script>
<body>
<form name="form1" method="post" action="">
<div id="userdata" style="display:none"></div><br><br>

<INPUT id="loadstring" type="button"  value="从指定网址得到图像"><img id="idtimage" src="http://verify.qq.com/getimage?0.9075894487369346">
<br>
<br>
<INPUT id="loadstring" type="button"  value="保存样本图片到数据岛">
<br>
<br>
<INPUT id="loadstring" type="button"  value="开始校验图片">
<br>
<br>
这里显示程序运行过程相关信息:
<input id="temp" type="text" width="100">
</form>
</body>
</html>
]]
wb:go("about:blank");
delay(100)
wb:wait("about")
wb:write(html);
wb:setTitle(true);
wb:setScroll(true);
delay(1000)
wb:wait("")
wb:show(true);
end;
--------------------------------------------------------------------------------------------------------------------
local timg = {}; --这是一个图像数组,用来储存还原后的验证码样本的图片数据
--必须进行一个转换,因为codekey里面只是base64编码的普通字符串,而timg 将是真正的图片对象(二进制数据)

---------------------------------还原到图片对象--------------------------------------------------------------
toImage = function(k,v)
    local img = image.new();
    local str = string.decode( v ,"");--首先进行base64解码,将纯文本转换为二进制数据
    img:setBytes( str ,"*.jpg");--将二进制数据还原为图像
    timg[k] = img;
end;
---------------------------------转换图片验证码到字符串的函数-----------------------------------------
function ImgToString(img)
    function test(imgX) --test是一个被包含在函数中的内部函数
        sleep(0);
        local limit = (60 * 20) + (60 * 20); --最小相似度 local关键字声明为局部变量
        local chr = "A"; --读取的字符
    
    
        --testimg是一个被包含在函数中的内部函数,作为table.foreach的回调函数,k参数表示键,v参数表示值
        testimg = function(k,v)
            --调用image.testXX()函数得出相似度,类似的函数还有image.testX() image.test()
            local n = imgX:testXX(timg[k]); --就是这个“图片比较”太垃圾,不然就没有问题了,55555
            if(n<limit)then --比较最小相似度
                  limit = n;
                  chr = k.."";
            end;
        end;
    
        --遍历timg表,并调用testimg函数
        for k,v in pairs(timg) do  
           testimg(k,v);  
        end;
        return string.left(chr,1); --返回读取到的字符串首字符(如果每个字符有多个样本)
    end;
    
    --修剪图片    
    --image.Crop(img, 1 ,2 , 37 ,18 )
    img:bpp(1);
    img:bpp(24);
    --上面的过程必须与下载样本时的代码完全一致。
    
    --使用split函数分割图片
    local img2,img3,img4,img5 = img:split(1,4);
    win.messagePrint("正在检测图片,请稍候....");
    return test(img2)..test(img3)..test(img4)..test(img5);
end;
-----------------------------------输出辨认结果-------------------------------------------
function showresult(str)
--下面我们把验证码的每个字符都转换为大写,并控制键盘顺序按键
code1 = string.upper( string.sub(str,1,1) );
code2 = string.upper( string.sub(str,2,2) );
code3 = string.upper( string.sub(str,3,3) );
code4 = string.upper( string.sub(str,4,4) );
win.consoleOpen()
print(code1);
print(code2);
print(code3);
print(code4);
end

-----------------------------------主调用-----------------------------------------------
wb=web.new();
write();--构建页面
sampleImg();--读取图片样本
tkey = ape:loadTable("验证码样本");
for k,v in pairs(tkey) do  --验证样本
    toImage(k,v); --转换为图像
end;
img = getImg();--读取图片
showresult(ImgToString(img));

猜你喜欢

转载自rainshow.iteye.com/blog/1076119