腾讯滑动验证破解测试(请勿用于商业用途)转载其他网站
using OpenQA.Selenium; using OpenQA.Selenium.Interactions; using OpenQA.Selenium.Chrome; using System; using System.Drawing; using System.Threading; using System.Text.RegularExpressions; namespace QQ_LoginTest { /* * nuget <package id="Selenium.Chrome.WebDriver" version="2.35" targetFramework="net452" /> <package id="Selenium.WebDriver" version="3.8.0" targetFramework="net452" /> */ class Program { static void Main(string[] args) { ChromeDriver driver = new ChromeDriver(); //(Iframe中拖动元素无效的问题)https://stackoverflow.com/questions/46271789/drag-and-drop-doesnt-work-inside-iframe-with-selenium-webdriver-with-java driver.Navigate().GoToUrl("https://qzone.qq.com/"); driver.Manage().Window.Maximize();//窗口最大化,便于脚本执行 //设置超时等待(隐式等待)时间设置10秒 driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10); IWebDriver login = driver.SwitchTo().Frame(driver.FindElementById("login_frame")); login.FindElement(By.Id("switcher_plogin")).Click(); login.FindElement(By.Id("u")).SendKeys("592955699");//QQ号码 login.FindElement(By.Id("p")).SendKeys("******");//QQ密码 if (login.FindElement(By.Id("err_m")).Text.Trim() == "请输入正确的帐号!") { Console.WriteLine("账号错误"); } else { //登陆QQ login.FindElement(By.Id("login_button")).Click(); } //获取到验证区域 IWebDriver validate = login.SwitchTo().Frame(login.FindElement(By.TagName("iframe"))); Thread.Sleep(2000); var slideBkg = validate.FindElement(By.Id("slideBlock"));//获取滑动验证图片 var tcOperationBkg = validate.FindElement(By.Id("tcOperation"));//获取整个验证图层 Console.WriteLine("Width "+slideBkg.Size.Width); Console.WriteLine("Height " + slideBkg.Size.Height); //例如(带阴影)地址:https://hy.captcha.qq.com/hycdn_1_1585770526512857856_0 //阴影小图 string yinyingUrl = slideBkg.GetAttribute("src"); //原图地址:https://hy.captcha.qq.com/hycdn_0_1585770526512857856_0 //用正则匹配并替换 //新大图 var newUrl= new Regex(@"hycdn_\d_", RegexOptions.Multiline).Replace(yinyingUrl, "hycdn_1_"); //原始大图 string oldUrl = new Regex(@"hycdn_\d_", RegexOptions.Multiline).Replace(yinyingUrl, "hycdn_0_"); //根据地址获取到图像 Console.WriteLine($"原始验证图地址:{oldUrl}"); Bitmap oldBmp = (Bitmap)LoginHelper.GetImg(oldUrl); Console.WriteLine($"阴影验证图地址:{newUrl}"); Bitmap newBmp = (Bitmap)LoginHelper.GetImg(newUrl); driver.GetScreenshot().SaveAsFile("原图.png"); oldBmp.Save("原始验证图.png"); newBmp.Save("阴影验证图.png"); int left = LoginHelper.GetArgb(oldBmp, newBmp);//得到阴影到图片左边界的像素 Console.WriteLine($"原始验证图起点:{left}"); var leftCount = (double)tcOperationBkg.Size.Width / (double)newBmp.Width * left; Console.WriteLine($"浏览器验证图起点:{leftCount}"); int leftShift = (int)leftCount - 30; Console.WriteLine($"实际移动:{leftShift}"); //int leftShift = (int)(left * ((double)slideBkg.Size.Width / (double)newBmp.Width) - 18);//得到真实的偏移值 //validate.SwitchTo(); var slideBlock = validate.FindElement(By.Id("slideBlock"));//获取到滑块 Console.WriteLine($"开始位置:{slideBlock.Location.X}"); Actions actions = new Actions(driver); //actions.ClickAndHold(slideBlock).Build().Perform(); //actions.DragAndDropToOffset(slideBlock, 50, 0).Perform(); //actions.Click(tcaptcha_drag_button).Perform(); //actions.ClickAndHold(tcaptcha_drag_button).Release().Perform(); actions.DragAndDropToOffset(slideBlock, leftShift, 0).Build().Perform();//单击并在指定的元素上按下鼠标按钮,然后移动到指定位置 //Thread.Sleep(2000); //Console.WriteLine($"移动后位置:{slideBlock.Location.X}"); //actions.DragAndDropToOffset(slideBlock,leftShift, 0).Perform();//移动滑块到阴影处 //Thread.Sleep(2000); driver.GetScreenshot().SaveAsFile("移动后图片.png"); } } }
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; namespace QQ_LoginTest { class LoginHelper { /// <summary> /// 截图 /// </summary> /// <param name="fromImagePath"></param> /// <param name="offsetX"></param> /// <param name="offsetY"></param> /// <param name="toImagePath"></param> /// <param name="width"></param> /// <param name="height"></param> public static void CaptureImage(byte[] fromImageByte, int offsetX, int offsetY, string toImagePath, int width, int height) { //原图片文件 MemoryStream ms = new MemoryStream(fromImageByte); Image fromImage = Image.FromStream(ms); //创建新图位图 Bitmap bitmap = new Bitmap(width, height); //创建作图区域 Graphics graphic = Graphics.FromImage(bitmap); //截取原图相应区域写入作图区 graphic.DrawImage(fromImage, 0, 0, new Rectangle(offsetX, offsetY, width, height), GraphicsUnit.Pixel); //从作图区生成新图 Image saveImage = Image.FromHbitmap(bitmap.GetHbitmap()); //保存图片 saveImage.Save(toImagePath, ImageFormat.Png); //释放资源 saveImage.Dispose(); graphic.Dispose(); bitmap.Dispose(); } /// <summary> /// 比较两张图片的像素,确定阴影图片位置 /// </summary> /// <param name="oldBmp"></param> /// <param name="newBmp"></param> /// <returns></returns> public static int GetArgb(Bitmap oldBmp, Bitmap newBmp) { //由于阴影图片四个角存在黑点(矩形1*1) for (int i = 0; i < newBmp.Width; i++) { for (int j = 0; j < newBmp.Height; j++) { if ((i>=0&&i<=1)&&((j>=0&&j<=1)||(j>= (newBmp.Height-2)&&j<=(newBmp.Height - 1)))) { continue; } if ((i >= (newBmp.Width-2) && i <= (newBmp.Width - 1)) && ((j >= 0 && j <= 1) || (j >= (newBmp.Height - 2) && j <= (newBmp.Height - 1)))) { continue; } //获取该点的像素的RGB的颜色 Color oldColor = oldBmp.GetPixel(i, j); Color newColor = newBmp.GetPixel(i, j); if (Math.Abs(oldColor.R - newColor.R) > 60 || Math.Abs(oldColor.G - newColor.G) > 60 || Math.Abs(oldColor.B - newColor.B) > 60) { return i; } } } return 0; } /// <summary> /// 根据图片地址,得到图片对象 /// </summary> /// <param name="url"></param> /// <returns></returns> public static Image GetImg(string url) { WebRequest webreq = WebRequest.Create(url); WebResponse webres = webreq.GetResponse(); Image img; using (System.IO.Stream stream = webres.GetResponseStream()) { img = Image.FromStream(stream); } return img; } } }
版权声明:本文为hujunmin原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。