C# 163邮箱自动登陆

引言

C# 学校邮箱自动登陆中我们使用WebBrowser控件轻松地完成了学校邮箱的登陆,但是如果想用这个办法来登录163邮箱,会找不到用户名、密码和登陆按钮这些元素。
注意:阅读本文前最好先阅读之前的C# 学校邮箱自动登陆

163邮箱的不同

打开163邮箱链接,同样的,检查邮箱账号元素,我们可以得到下面这张图,网页中确实是存在邮箱账号元素的,而且类似学校的邮箱,是在一个input元素中,但是注意图片中红色框中的部分,这个input元素不是位于当前HTML框架里,而是一个iframe元素代表的内联HTML框架里。看到这里,第一想法先选择这个内联框架,然后用类似下面的语句去找到input元素,程序一运行你就会得到一个unauthorized error。这是因为webBrowser不支持上层应用对内联框架(iframe)的跨域访问。

var elements = webBrowser1.Document.Window.Frames["x-URS-iframe"].Document.GetElementsByTagName("input");
HtmlElement id = null;
HtmlElement pwd = null;
foreach (HtmlElement ele in elements)
{
    if (ele.GetAttribute("name") == "email")
         id = ele;           
    if (ele.GetAttribute("name") == "password")
         pwd = ele;
}     

C# 163邮箱自动登陆

解决方案

WebBrowser本身是调用了IE,既然它不支持应用对内联框架的访问,我们可以考虑给应用换一个浏览器内核,比如Chrome或者FireFox。这里有一个非常好用的类库帮我们解决C#调用Chrome和FireFox的底层问题,并且提供了非常强大的元素选择操作,以及支持应用对内联框架的访问,它就是Selenium。Selenium提供了NuGet的安装方式,直接打开工具->NuGet包管理器->管理解决方案的NuGet包,然后搜索Selenium就可以选择安装,本文使用的是Chrome内核,因此需要安装两个NuGet包,Selenium.WebDriver和Selenium.Chrome.WebDriver。
C# 163邮箱自动登陆
通过Selenium官方参考手册可以大致了解其用法,本文首先创建了一个控制台应用,使用代码如***意需要引入两个命名空间。

using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace _163Mail
{
    class Program
    {
        static void Main(string[] args)
        {
            IWebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(1);
            string url = "https://mail.163.com";
            driver.Navigate().GoToUrl(url);
            driver.SwitchTo().Frame("x-URS-iframe");
            driver.FindElement(By.Name("email")).SendKeys("lincherryclf");
            driver.FindElement(By.Name("password")).SendKeys("crhxxl12280104");
            driver.FindElement(By.Id("dologin")).Click();
        }
    }
}