使用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("账号", "密码");