自动识别点触验证码

1. 目标
本节的目标是使用 C# 语言通过程序自动识别并通过点触验证码。

2. 准备工作
我们将使用 C# 的 Selenium 库和 Chrome 浏览器。请确保已经安装好了 Selenium WebDriver 和 Chrome 浏览器,并配置好了 ChromeDriver。相关的安装和配置可以参考 Selenium 官方文档。

3. 了解点触验证码
点触验证码是一种需要用户点击图像中特定文字或图案的验证方式。此类验证码的识别难度较大,因此我们将借助第三方验证码识别平台(如超级鹰)来实现自动化。

4. 识别思路
直接通过图像识别技术来识别点触验证码难度较大,尤其是复杂的文字和图像。我们将利用超级鹰提供的服务,通过提交验证码图片获取识别结果,然后模拟点击识别出的坐标位置。

5. 注册账号
首先需要注册一个超级鹰账号并申请一个软件 ID。可以在超级鹰官网进行注册。注册完成后,在开发者中心添加一个软件 ID,并充值一些题分。

6. 获取 API
超级鹰提供了适用于 C# 的 API。以下是 C# 的 API 实现代码:

csharp

using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

public class Chaojiying
{
    private string username;
    private string password;
    private string softId;

    public Chaojiying(string username, string password, string softId)
    {
        this.username = username;
        this.password = GetMd5Hash(password);
        this.softId = softId;
    }

    private string GetMd5Hash(string input)
    {
        using (var md5 = MD5.Create())
        {
            var data = md5.ComputeHash(Encoding.UTF8.GetBytes(input));
            var sb = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sb.Append(data[i].ToString("x2"));
            }
            return sb.ToString();
        }
    }

    public async Task<Dictionary<string, object>> PostPic(byte[] img, int codeType)
    {
        using (var client = new HttpClient())
        {
            using (var content = new MultipartFormDataContent())
            {
                content.Add(new StringContent(username), "user");
                content.Add(new StringContent(password), "pass2");
                content.Add(new StringContent(softId), "softid");
                content.Add(new StringContent(codeType.ToString()), "codetype");
                content.Add(new ByteArrayContent(img), "userfile", "captcha.jpg");

                var response = await client.PostAsync("http://upload.chaojiying.net/Upload/Processing.php", content);
                var responseString = await response.Content.ReadAsStringAsync();
                return JsonConvert.DeserializeObject<Dictionary<string, object>>(responseString);
            }
        }
    }

    public async Task<Dictionary<string, object>> ReportError(string imgId)
    {
        using (var client = new HttpClient())
        {
            var content = new MultipartFormDataContent
            {
                { new StringContent(username), "user" },
                { new StringContent(password), "pass2" },
                { new StringContent(softId), "softid" },
                { new StringContent(imgId), "id" }
            };

            var response = await client.PostAsync("http://upload.chaojiying.net/Upload/ReportError.php", content);
            var responseString = await response.Content.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<Dictionary<string, object>>(responseString);
        }
    }
}
7. 初始化
首先,我们初始化一些变量和对象,如 WebDriver 和 Chaojiying 对象:

csharp

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System;
using System.Drawing;
using System.IO;
using System.Threading.Tasks;

public class CrackTouClick
{
    private static readonly string Email = "your_email@example.com";
    private static readonly string Password = "your_password";
    private static readonly string ChaojiyingUsername = "your_username";
    private static readonly string ChaojiyingPassword = "your_password";
    private static readonly string ChaojiyingSoftId = "your_soft_id";
    private static readonly int ChaojiyingKind = 9102;

    private IWebDriver driver;
    private Chaojiying chaojiying;

    public CrackTouClick()
    {
        var options = new ChromeOptions();
        options.AddArgument("--headless");
        driver = new ChromeDriver(options);
        chaojiying = new Chaojiying(ChaojiyingUsername, ChaojiyingPassword, ChaojiyingSoftId);
    }

    public void Open()
    {
        driver.Navigate().GoToUrl("http://admin.touclick.com/login.html");
        var emailField = driver.FindElement(By.Id("email"));
        var passwordField = driver.FindElement(By.Id("password"));
        emailField.SendKeys(Email);
        passwordField.SendKeys(Password);
    }

    public IWebElement GetTouClickButton()
    {
        return driver.FindElement(By.ClassName("touclick-hod-wrap"));
    }

    public IWebElement GetTouClickElement()
    {
        return driver.FindElement(By.ClassName("touclick-pub-content"));
    }

    public Rectangle GetPosition()
    {
        var element = GetTouClickElement();
        var location = element.Location;
        var size = element.Size;
        return new Rectangle(location.X, location.Y, size.Width, size.Height);
    }

    public async Task<byte[]> GetScreenshot()
    {
        var screenshot = ((ITakesScreenshot)driver).GetScreenshot();
        return screenshot.AsByteArray;
    }

    public async Task<Bitmap> GetTouClickImage()
    {
        var screenshotBytes = await GetScreenshot();
        using (var ms = new MemoryStream(screenshotBytes))
        {
            var screenshot = new Bitmap(ms);
            var position = GetPosition();
            return screenshot.Clone(position, screenshot.PixelFormat);
        }
    }

    public async Task<Dictionary<string, object>> RecognizeCaptcha()
    {
        var image = await GetTouClickImage();
        using (var ms = new MemoryStream())
        {
            image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
            return await chaojiying.PostPic(ms.ToArray(), ChaojiyingKind);
        }
    }
}
8. 识别验证码
调用 Chaojiying 对象的 PostPic 方法提交图片进行识别,并获取识别结果。代码如下:

csharp

public async Task PerformTouClick()
{
    Open();
    GetTouClickButton().Click();
    await Task.Delay(2000); // 等待验证码加载  更多内容联系1436423940

    var result = await RecognizeCaptcha();
    Console.WriteLine(result);

    if (result.TryGetValue("pic_str", out var picStr) && picStr is string coordinates)
    {
        var locations = GetPoints(coordinates);
        TouchClickWords(locations);
    }
}

public List<Point> GetPoints(string coordinates)
{
    var points = new List<Point>();
    var groups = coordinates.Split('|');

    foreach (var group in groups)
    {
        var parts = group.Split(',');
        points.Add(new Point(int.Parse(parts[0]), int.Parse(parts[1])));
    }

    return points;
}

public void TouchClickWords(List<Point> locations)
{
    var element = GetTouClickElement();
    foreach (var location in locations)
    {
        new OpenQA.Selenium.Interactions.Actions(driver)
            .MoveToElement(element, location.X, location.Y)
            .Click()
            .Perform();
        Task.Delay(1000).Wait();
    }
}

  • 23
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值