模拟登录之解析验证码

时间:2022-08-31 12:18:38
目标网址:http://www.paperpass.org/login.aspx
网站没升级之前,可以正常解析验证码,但是网站升级后,解析不了了,各位大虾帮忙看下

    /// <summary>
    /// 获取验证码
    /// </summary>
    /// <param name="cc">Cookie 容器</param>
    /// <returns></returns>
    private string GetValidateImageCode(CookieContainer cc)
    {
        string strResult = "";

        /// 获取验证码地址
        string strImageUrl = "";
        string srcString = GetHtml("http://www.paperpass.org/login.aspx", "GET", "", "utf-8", cc);
        if (srcString.IndexOf("login.aspx?_ImageTag") > 0)
        {
            strImageUrl = srcString.Substring(srcString.IndexOf("login.aspx?_ImageTag"));
            strImageUrl = "http://www.paperpass.org/" + strImageUrl.Substring(0, strImageUrl.IndexOf("\""));

            __viewStateValue = GetViewState(srcString);
            __eventValidation = GetEventValidation(srcString);
        }
        if (strImageUrl.Trim().Length < 1) { return srcString; }

        // cookie 容器
        CookieCollection myCookieCollection = new CookieCollection();
        HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(strImageUrl.Trim());
        myRequest.MaximumAutomaticRedirections = 4;
        myRequest.MaximumResponseHeadersLength = 4;
        myRequest.Method = "GET";
        myRequest.Accept = "image/png, image/svg+xml, image/*;q=0.8, */*;q=0.5";
        myRequest.KeepAlive = true;
        myRequest.Timeout = 300000;
        myRequest.ServicePoint.Expect100Continue = false;
        myRequest.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
        myRequest.ContentType = "application/x-www-form-urlencoded";
        myRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1;.NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET4.OE; .NET4.0C; Trident/5.0)";
        myRequest.CookieContainer = cc;
        myRequest.ContentLength = 0;

        /// 结果
        HttpWebResponse myResponse = null;
        try
        {
            myResponse = (HttpWebResponse)myRequest.GetResponse();
            myCookieCollection = myResponse.Cookies;
            if (myCookieCollection.Count < 1)
            {
                myCookieCollection = cc.GetCookies(myRequest.RequestUri);
            }

            /// 取SessionID
            __paperPassSessionId = "";
            if (myCookieCollection.Count > 0)
            {
                foreach (Cookie c in myCookieCollection)
                {
                    if (c.Name.ToLower().Trim() == "asp.net_sessionid")
                    {
                        __paperPassSessionId = c.Value;
                        break;
                    }
                }
            }

            /// 下载验证码图片
            using (System.IO.Stream responseStream = myResponse.GetResponseStream())
            {
                int readSize = 0;
                byte[] buffer = new byte[32 * 1024];
                MemoryStream ms = new MemoryStream();
                while ((readSize = responseStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, readSize);
                }
                ms.Position = 0;

                /// 解析验证码
                Bitmap _OldBitmap = (Bitmap)System.Drawing.Image.FromStream(ms);
                ms.Close();

                try
                {
                    UnCodebase ucb = new UnCodebase(_OldBitmap);

                    strResult = "";
                    ucb.GrayByPixels();                         //灰度处理
                    ucb.GetPicValidByValue(128, 4);             //得到有效空间
                    Bitmap[] pics = ucb.GetSplitPics(4,1);     //分割
                    if (pics.Length == 4)
                    {
                        pics[0] = ucb.GetPicValidByValue(pics[0], 128);
                        pics[1] = ucb.GetPicValidByValue(pics[1], 128);
                        pics[2] = ucb.GetPicValidByValue(pics[2], 128);
                        pics[3] = ucb.GetPicValidByValue(pics[3], 128);
                        for (int i = 0; i < pics.Length; i++)
                        {
                            strResult += ucb.GetSingleBmpCodeValue(ucb.GetSingleBmpCode(pics[i], 128));
                        }
                    }
                    for (int i = 0; i < pics.Length; i++)
                    {
                        pics[i].Dispose();
                    }
                }
                catch { }
                _OldBitmap.Dispose();
            }
            myResponse.Close();
            myResponse = null;
        }
        catch { }
        if (myResponse != null) { myResponse.Close(); }
        myRequest.Abort();

        return strResult.Trim();
    }

7 个解决方案

#1


UnCodebase类,分两次发


using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;


/// <summary>
/// 解析验证码
/// </summary>
public class UnCodebase
{
    public Bitmap bmpobj;
    public UnCodebase(Bitmap pic)
    {
        bmpobj = new Bitmap(pic);    //转换为Format32bppRgb
    }

    /// <summary>
    /// 根据RGB,计算灰度值
    /// </summary>
    /// <param name="posClr">Color值</param>
    /// <returns>灰度值,整型</returns>
    private int GetGrayNumColor(System.Drawing.Color posClr)
    {
        return (posClr.R * 19595 + posClr.G * 38469 + posClr.B * 7472) >> 16;
    }

    /// <summary>
    /// 灰度转换,逐点方式
    /// </summary>
    public void GrayByPixels()
    {
        for (int i = 0; i < bmpobj.Height; i++)
        {
            for (int j = 0; j < bmpobj.Width; j++)
            {
                int tmpValue = GetGrayNumColor(bmpobj.GetPixel(j, i));
                if (tmpValue == 204) { tmpValue = 255; }
                bmpobj.SetPixel(j, i, Color.FromArgb(tmpValue, tmpValue, tmpValue));
            }
        }
    }

    /// <summary>
    /// 得到有效图形并调整为可平均分割的大小
    /// </summary>
    /// <param name="dgGrayValue">灰度背景分界值</param>
    /// <param name="CharsCount">有效字符数</param>
    /// <returns></returns>
    public void GetPicValidByValue(int dgGrayValue, int CharsCount)
    {
        int posx1 = bmpobj.Width; int posy1 = bmpobj.Height;
        int posx2 = 0; int posy2 = 0;
        for (int i = 0; i < bmpobj.Height; i++)      //找有效区
        {
            for (int j = 0; j < bmpobj.Width; j++)
            {
                int pixelValue = bmpobj.GetPixel(j, i).R;
                if (pixelValue < dgGrayValue)     //根据灰度值
                {
                    if (posx1 > j) posx1 = j;
                    if (posy1 > i) posy1 = i;

                    if (posx2 < j) posx2 = j;
                    if (posy2 < i) posy2 = i;
                };
            };
        };
        // 确保能整除
        int Span = CharsCount - (posx2 - posx1 + 1) % CharsCount;   //可整除的差额数
        if (Span < CharsCount)
        {
            int leftSpan = Span / 2;    //分配到左边的空列 ,如span为单数,则右边比左边大1
            if (posx1 > leftSpan)
                posx1 = posx1 - leftSpan;
            if (posx2 + Span - leftSpan < bmpobj.Width)
                posx2 = posx2 + Span - leftSpan;
        }
        //复制新图
        Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1);
        bmpobj = bmpobj.Clone(cloneRect, bmpobj.PixelFormat);
    }

    /// <summary>
    /// 得到有效图形,图形由外面传入
    /// </summary>
    /// <param name="dgGrayValue">灰度背景分界值</param>
    /// <param name="CharsCount">有效字符数</param>
    /// <returns></returns>
    public Bitmap GetPicValidByValue(Bitmap singlepic, int dgGrayValue)
    {
        int posx1 = singlepic.Width; int posy1 = singlepic.Height;
        int posx2 = 0; int posy2 = 0;
        for (int i = 0; i < singlepic.Height; i++)      //找有效区
        {
            for (int j = 0; j < singlepic.Width; j++)
            {
                int pixelValue = singlepic.GetPixel(j, i).R;
                if (pixelValue < dgGrayValue)     //根据灰度值
                {
                    if (posx1 > j) posx1 = j;
                    if (posy1 > i) posy1 = i;

                    if (posx2 < j) posx2 = j;
                    if (posy2 < i) posy2 = i;
                };
            };
        };
        //复制新图
        Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1);
        return singlepic.Clone(cloneRect, singlepic.PixelFormat);
    }

#2


这么简单的事情... 

#3


这么简单的事情

#4


这么觉得的事情...............嘿

#5


网站 升级了,你先看是不是验证码 识别的问题,是不是其他的问题,如果确定是验证码的问题,你这个程序应该没多大问题,在于 你的模版有问题了,让你的程序 重新学习一遍就OK了,你这个验证码没什么难度

#6


GetSingleBmpCodeValue 这方法在哪???

#7


模拟登录之解析验证码

这种验证码很好处理的。用一个OCR实别率很高的

#1


UnCodebase类,分两次发


using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;


/// <summary>
/// 解析验证码
/// </summary>
public class UnCodebase
{
    public Bitmap bmpobj;
    public UnCodebase(Bitmap pic)
    {
        bmpobj = new Bitmap(pic);    //转换为Format32bppRgb
    }

    /// <summary>
    /// 根据RGB,计算灰度值
    /// </summary>
    /// <param name="posClr">Color值</param>
    /// <returns>灰度值,整型</returns>
    private int GetGrayNumColor(System.Drawing.Color posClr)
    {
        return (posClr.R * 19595 + posClr.G * 38469 + posClr.B * 7472) >> 16;
    }

    /// <summary>
    /// 灰度转换,逐点方式
    /// </summary>
    public void GrayByPixels()
    {
        for (int i = 0; i < bmpobj.Height; i++)
        {
            for (int j = 0; j < bmpobj.Width; j++)
            {
                int tmpValue = GetGrayNumColor(bmpobj.GetPixel(j, i));
                if (tmpValue == 204) { tmpValue = 255; }
                bmpobj.SetPixel(j, i, Color.FromArgb(tmpValue, tmpValue, tmpValue));
            }
        }
    }

    /// <summary>
    /// 得到有效图形并调整为可平均分割的大小
    /// </summary>
    /// <param name="dgGrayValue">灰度背景分界值</param>
    /// <param name="CharsCount">有效字符数</param>
    /// <returns></returns>
    public void GetPicValidByValue(int dgGrayValue, int CharsCount)
    {
        int posx1 = bmpobj.Width; int posy1 = bmpobj.Height;
        int posx2 = 0; int posy2 = 0;
        for (int i = 0; i < bmpobj.Height; i++)      //找有效区
        {
            for (int j = 0; j < bmpobj.Width; j++)
            {
                int pixelValue = bmpobj.GetPixel(j, i).R;
                if (pixelValue < dgGrayValue)     //根据灰度值
                {
                    if (posx1 > j) posx1 = j;
                    if (posy1 > i) posy1 = i;

                    if (posx2 < j) posx2 = j;
                    if (posy2 < i) posy2 = i;
                };
            };
        };
        // 确保能整除
        int Span = CharsCount - (posx2 - posx1 + 1) % CharsCount;   //可整除的差额数
        if (Span < CharsCount)
        {
            int leftSpan = Span / 2;    //分配到左边的空列 ,如span为单数,则右边比左边大1
            if (posx1 > leftSpan)
                posx1 = posx1 - leftSpan;
            if (posx2 + Span - leftSpan < bmpobj.Width)
                posx2 = posx2 + Span - leftSpan;
        }
        //复制新图
        Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1);
        bmpobj = bmpobj.Clone(cloneRect, bmpobj.PixelFormat);
    }

    /// <summary>
    /// 得到有效图形,图形由外面传入
    /// </summary>
    /// <param name="dgGrayValue">灰度背景分界值</param>
    /// <param name="CharsCount">有效字符数</param>
    /// <returns></returns>
    public Bitmap GetPicValidByValue(Bitmap singlepic, int dgGrayValue)
    {
        int posx1 = singlepic.Width; int posy1 = singlepic.Height;
        int posx2 = 0; int posy2 = 0;
        for (int i = 0; i < singlepic.Height; i++)      //找有效区
        {
            for (int j = 0; j < singlepic.Width; j++)
            {
                int pixelValue = singlepic.GetPixel(j, i).R;
                if (pixelValue < dgGrayValue)     //根据灰度值
                {
                    if (posx1 > j) posx1 = j;
                    if (posy1 > i) posy1 = i;

                    if (posx2 < j) posx2 = j;
                    if (posy2 < i) posy2 = i;
                };
            };
        };
        //复制新图
        Rectangle cloneRect = new Rectangle(posx1, posy1, posx2 - posx1 + 1, posy2 - posy1 + 1);
        return singlepic.Clone(cloneRect, singlepic.PixelFormat);
    }

#2


这么简单的事情... 

#3


这么简单的事情

#4


这么觉得的事情...............嘿

#5


网站 升级了,你先看是不是验证码 识别的问题,是不是其他的问题,如果确定是验证码的问题,你这个程序应该没多大问题,在于 你的模版有问题了,让你的程序 重新学习一遍就OK了,你这个验证码没什么难度

#6


GetSingleBmpCodeValue 这方法在哪???

#7


模拟登录之解析验证码

这种验证码很好处理的。用一个OCR实别率很高的