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 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/hujunmin/p/11486124.html