近期准备做一个EMS免验证码的单号查询系统,思路是先用程序自动识别验证码,然后再用CURL方法模拟浏览器访问.EMS网站改版了,新版的验证码是6位数字.详情可以访问www.ems.com.cn现在已经做到用程序可以正确识别验证码,(已经证实验证码识别程序代码正确,下面有代码示例可以测试验证.)但通过程序识别得到的验证码,EMS网站结果页面老是提示验证码错误, EMS一直接受 
< img src='http://www.11183.com.cn/ems/rand' > 这样显示在网页上的验证码.请高手看看什么原因?大家可以下载源代码代码在自己的机器上测试下.
<?php
$imgPath = 'http://www.11183.com.cn/ems/rand';echo "EMS一直接受 &lt img src='http://www.11183.com.cn/ems/rand' &gt 这样显示在网页上的验证码<br/>";echo '<br><img src='.$imgPath .'><br><br>';echo "无论重复几次 &lt img src='http://www.11183.com.cn/ems/rand' &gt 验证码也不会改变,按道理说每访问一次http://www.11183.com.cn/ems/rand 验证码应该改变<br>";
echo '<br><img src='.$imgPath .'><br>';echo "<br>通过验证码识别程序访问 http://www.11183.com.cn/ems/rand 得到的验证码:<br>";$code= crackValidateCode($imgPath);
echo $code;
echo "<br><br>此时通过验证码程序又访问了一次
http://www.11183.com.cn/ems/rand,为什么EMS服务器里的session 密码值还是刚才图片里显示的?难倒没有改变? <BR><BR>";?><form action="http://www.11183.com.cn/ems/order/singleQuery_e" method="post" id="singleForm">
<input id="mailNum" type="text"  maxlength="13" name="mailNum" value="LK165977610CN">
<input type="text" autocomplete="off" name="checkCode" id="verification_code" value="<?php echo $code;?>">
<input type="submit" value="Track EMS">
</form><br>输入图片里的验证码数字就可以查询结果,输入验证码识别程序里的数字就会显示验证码错误<br><br>
<hr></hr>
<br>
验证码识别程序正确性测试,<br>下面几个图片已经保存在本程序代码的同目录下:<br><br>测试一:<img src="test1.jpg"> 验证码是:<?php echo crackValidateCode('test1.jpg');?> <br><br>测试二:<img src="test2.jpg"> 验证码是:<?php echo crackValidateCode('test2.jpg');?> <br><br>测试三:<img src="test3.jpg"> 验证码是:<?php echo crackValidateCode('test3.jpg');?> <br><br><?php 
function crackValidateCode($imgPath)
{

if (''==$imgPath)  return '';
//if(!file_exists($imgPath)) return '~~~图片文件不存在.~~~';

define('WORD_WIDTH',9);
define('WORD_HIGHT',13);
define('OFFSET_X',7);
define('OFFSET_Y',3);
define('WORD_SPACING',4);$DataArray = array();
$ImageSize = array();
$data = array();
$Keys = array(
'0'=>'000111000011111110011000110110000011110000
0111100000111100000111100000111100000
11110000011011000110011111110000111000',
'1'=>'000111000011111000011111000000011000000011000000011000000
0110000000110000000110000000110000000
11000011111111011111111',
'2'=>'0111110001111111001000001100000001110000001100000011000000
110000001100000011000000110000001100
00000011111110111111110',
'3'=>'01111100011111111010000011000000011000000110001111100001111
11000000011100000001110000001101000
01110111111100011111000',
'4'=>'000001100000011100000011100000111100001101100001101100011001
1000110011001111111111111111110000
01100000001100000001100',
'5'=>'1111111101111111101100000001100000001100
0000011111000011111110000000111000
00001110000001101000
01110111111100011111000',
'6'=>'00011110000111111001100001001100000011000000011011
11001111111101110001111100000111100000110110
00111011111110000111100',
'7'=>'0111111110111111110000000110000000100000001100000011000
000010000000110000000100000001100000001
10000001100000001100000',
'8'=>'00111110001111111001100011001100011001110111000111110
00011111000111011101100000111100000111110
00111011111110001111100',
'9'=>'00111100001111111011100011111000001111000001111100011
10111111110011110110000000110000001100100
00110011111100001111000',
);

$NumStringArray = array();$size = getimagesize($imgPath);
$res = imagecreatefromjpeg($imgPath);$tmpdata = array();
for($i=0; $i < $size[1]; ++$i)
{
for($j=0; $j < $size[0]; ++$j)
{
$rgb = imagecolorat($res,$j,$i);
$rgbarray = imagecolorsforindex($res, $rgb);
if($rgbarray['red'] < 125 || $rgbarray['green']<125
|| $rgbarray['blue'] < 125)
{
$tmpdata[$i][$j]=1;
}else{
$tmpdata[$i][$j]=0;
}
}
}$DataArray = $tmpdata;
$ImageSize = $size;$result="";
// 查找6个数字
$codeArray = array("","","","","","");
for($i=0;$i<6;++$i)
{
$x = ($i*(WORD_WIDTH+WORD_SPACING))+OFFSET_X;
$y = OFFSET_Y;
for($h = $y; $h < (OFFSET_Y+WORD_HIGHT); ++ $h)
{
for($w = $x; $w < ($x+WORD_WIDTH); ++$w)
{
$codeArray[$i].=$DataArray[$h][$w];
}
}
}// 进行关键字匹配
foreach($codeArray as $numKey => $numString)
{
$max=0.0;
$num = 0;
foreach($Keys as $key => $value)
{
$percent=0.0;
similar_text($value, $numString,$percent);
if(intval($percent) > $max)
{
$max = $percent;
$num = $key;
if(intval($percent) > 95)
break;
}
}
$result.=$num;
}
return $result;}
?>

解决方案 »

  1.   

    思路不错…你要成功,就要模拟到位将请求验证图片的的cookie保存下来,然后分析图片上的数字,接着将数字、cookie及相应的单号信息等一起提交给ems服务器
      

  2.   

    你都没有得到验证码头部的COOKIE,就算识别了,服务器又怎么知道是哪个图片被识别了呢?
      

  3.   

    EMS网站结果页面老是提示验证码错误
    这与验证码识别没多大关系,因为再复杂的验证码都可以通过转接到人工识别来解决
    关键在于 cookie 是否被完整的传递了
      

  4.   

    主要就是会话ID错了,这EMS网站认为是两次会话了。
      

  5.   

    我使用C#写的  winform  用post数据的方法 将 EMS运单号 和 验证码都传递过去 
    在获取验证码的时候 使用GET 然后带cookie  最后将这个 cookie一起POST回去  
    目前我这边都运行正常
      

  6.   

    补充下 获取验证码的地址  string strImageUrl = "http://www.ems.com.cn/ems/rand?d=";
    获取完一次验证码之后 重新构造下 图片链接 
    Random r = new Random();
    strImageUrl = strImageUrl + r.Next();
      

  7.   

    你没交COOKIE人家怎么追踪你的SESSION.