使用Selenium自动登录12306

12306 登录

环境

.NetFramework4.5

Selenium.WebDriver 3.141.0

chromedriver.exe 97.0.4692.X (从 http://chromedriver.storage.googleapis.com/index.html 下载)

Crawler

public class Crawler
    {
        public static Crawler Instance = new Lazy<Crawler>(() => new Crawler()).Value;

        private IWebDriver webDriver = null;
        private IWait<IWebDriver> webDriverWait = null;

        private static ChromeDriverService GetChromeDriverService()
        {
            var pds = ChromeDriverService.CreateDefaultService("driver");
            //设置代理服务器地址
            //pds.Proxy = $"{ip}:{port}";  
            //设置代理服务器认证信息
            //pds.ProxyAuthentication = GetProxyAuthorization();
            //隐藏命令行窗口
            pds.HideCommandPromptWindow = true;
            return pds;
        }

        public IWebDriver CreateWebDriver(bool hideChrome = true)
        {
            if (webDriver != null)
            {
                return webDriver;
            }
            var options = new ChromeOptions();
            if (hideChrome)
            {
                options.AddArgument("headless");
            }

            webDriver = new ChromeDriver(GetChromeDriverService(), options);

            //关闭 webdriver
            CloseWebDriver(webDriver as ChromeDriver);

            return webDriver;
        }

        /// <summary>
        /// 关闭webdriver
        /// 阿里验证码滑块会校验此标志
        /// </summary>
        /// <param name="chromeDriver"></param>
        private void CloseWebDriver(ChromeDriver chromeDriver)
        {
            //window.navigator.webdriver=false
            var dics = new Dictionary<string, object>();
            dics["source"] = @"
            Object.defineProperty(navigator, 'webdriver', {
                  get: () => undefined
                })
            ";
            chromeDriver.ExecuteChromeCommand("Page.addScriptToEvaluateOnNewDocument", dics);
        }

        public IWait<IWebDriver> GetWebDriverWait(int seconds = 5)
        {
            if (webDriverWait != null)
            {
                return webDriverWait;
            }
            webDriverWait = new OpenQA.Selenium.Support.UI.WebDriverWait(webDriver, TimeSpan.FromSeconds(seconds));
            //忽略未找到元素的异常
            webDriverWait.IgnoreExceptionTypes(typeof(NoSuchElementException));
            return webDriverWait;
        }

        public void Disposable()
        {
            if (webDriver != null)
            {
                try
                {
                    webDriver.Quit();
                    webDriver.Dispose();
                    webDriver = null;
                    webDriverWait = null;
                }
                catch { }
            }
        }
    }

_12306

public class _12306
    {

        ~_12306()
        {
            Dispose();
        }

        public void Dispose()
        {
            if (Driver != null)
            {
                Driver.Quit();
                Driver.Dispose();
            }
        }

        private IWebDriver Driver;
        private IWait<IWebDriver> Wait;
        private string Code;
        public _12306(IWebDriver driver, IWait<IWebDriver> wait)
        {
            this.Driver = driver;
            this.Wait = wait;
        }

        public void To(string url)
        {
            Driver.Navigate().GoToUrl(url);
        }

        private void InputAccount(string account, string pwd)
        {
            Driver.FindElement(By.Id("J-userName")).SendKeys(account);
            Driver.FindElement(By.Id("J-password")).SendKeys(pwd);
        }

        private void ClickLogin()
        {
            Driver.FindElement(By.Id("J-login")).Click();
        }

        private void Drag()
        {
            var webElement = Driver.FindElement(By.Id("J-slide-passcode"));

            var span = Wait.Until(p =>
            {
                var sw = Stopwatch.StartNew();
                while (sw.ElapsedMilliseconds < 3000)
                {
                    try
                    {
                        return webElement.FindElement(By.Id("nc_1_n1z"));
                    }
                    catch (Exception ex)
                    {
                    }
                }
                return null;
            });

            Actions action = new Actions(this.Driver);
            action.ClickAndHold(span).Perform();
            //模拟人手动
            //Thread.Sleep(100);
            //action.MoveByOffset(226, 1);
            //Thread.Sleep(87);
            //action.MoveByOffset(256, 1);
            //Thread.Sleep(115);
            action.MoveByOffset(300, 0);
            //Thread.Sleep(200);
            action.Release();
        }

        public void Login(string account = "", string pwd = "")
        {
            To("https://kyfw.12306.cn/otn/resources/login.html");
            InputAccount(account, pwd);
            ClickLogin();
            Drag();
        }

        public void Switch(string departure, string arrive)
        {
            //车站id:https://kyfw.12306.cn/otn/resources/js/framework/station_name.js?station_version=1.9018

            var fromCookie = new OpenQA.Selenium.Cookie("_jc_save_fromStation", "上海,SHH");
            var toCookie = new OpenQA.Selenium.Cookie("_jc_save_toStation", "北京,BJP");
            var dateCookie = new OpenQA.Selenium.Cookie("_jc_save_toDate", "2022-01-05");
            Driver.Manage().Cookies.AddCookie(fromCookie);
            Driver.Manage().Cookies.AddCookie(toCookie);
            Driver.Manage().Cookies.AddCookie(dateCookie);

            To("https://kyfw.12306.cn/otn/leftTicket/init?linktypeid=dc");

            var closeTips = Wait.Until(p =>
             {
                 var sw = Stopwatch.StartNew();
                 while (sw.ElapsedMilliseconds < 3000)
                 {
                     try
                     {
                         return Driver.FindElement(By.Id("qd_closeDefaultWarningWindowDialog_id"));
                     }
                     catch (Exception ex)
                     {

                     }
                 }
                 return null;
             });
            if (closeTips != null)
                closeTips.Click();
            Thread.Sleep(100);

            Driver.FindElement(By.Id("query_ticket")).Click();

            var table = Driver.FindElement(By.Id("queryLeftTable"));
            var trs = table.FindElements(By.TagName("tr"));

            var tranNoArr = new string[] { "G104", };

            for (int i = 1; i < trs.Count; i++)
            {
                var pre = trs[i - 1];
                var cur = trs[i];
                if (tranNoArr.Contains(cur.GetAttribute("datatran")))
                {
                    var tds = pre.FindElements(By.TagName("td"));
                    if (tds.Count >= 4 && tds[4].Text != "--")
                    {
                        var btn = tds[4].FindElement(By.ClassName("btn72"));
                        btn.Click();
                    }
                }
            }
        }
    }

使用

var driver = Crawler.Instance.CreateWebDriver(false);
var wait = Crawler.Instance.GetWebDriverWait();
var _ = new _12306(driver, wait);
_.Login("账号", "密码");

参考 https://www.selenium.dev/

posted @ 2022-01-17 14:33  划破黑夜  阅读(157)  评论(0编辑  收藏  举报