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;
}     

在这里插入图片描述

解决方案

WebBrowser本身是调用了IE,既然它不支持应用对内联框架的访问,我们可以考虑给应用换一个浏览器内核,比如Chrome或者FireFox。这里有一个非常好用的类库帮我们解决C#调用Chrome和FireFox的底层问题,并且提供了非常强大的元素选择操作,以及支持应用对内联框架的访问,它就是Selenium。Selenium提供了NuGet的安装方式,直接打开工具->NuGet包管理器->管理解决方案的NuGet包,然后搜索Selenium就可以选择安装,本文使用的是Chrome内核,因此需要安装两个NuGet包,Selenium.WebDriver和Selenium.Chrome.WebDriver。
在这里插入图片描述
通过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();
        }
    }
}


20181030更新

今天打开前两天写的163邮箱自动登陆程序,运行出错,说找不到名字或ID为“x-URS-iframe”的组件,查看 163邮箱页面源代码,发现iframe元素的ID已经发生改变,在原先的“x-URS-iframe”后面跟了一串随机数字,为了跳转到这个内联框架,首先需要获取iframe元素的ID属性值IDValue,最后在上述代码中添加了获取IDValue部分,从而解决了这个问题。
在这里插入图片描述

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

namespace _163Mail
{
    class Program
    {
        static void Main(string[] args)
        {
            IWebDriver driver = new ChromeDriver();
            string url = "https://mail.163.com";
            driver.Navigate().GoToUrl(url);
            System.Threading.Thread.Sleep(500);
            var frameCol = driver.FindElements(By.TagName("iframe"));
            string iframe = null;
            foreach(var frame in frameCol)
            {
                if (frame.GetAttribute("id").StartsWith("x-URS-iframe"))
                {
                    iframe = frame.GetAttribute("id");
                }    
            }

            driver.SwitchTo().Frame(iframe);
            driver.FindElement(By.Name("email")).SendKeys("lincherryclf");
            driver.FindElement(By.Name("password")).SendKeys("crhxxl12280104");
            driver.FindElement(By.Id("dologin")).Click();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/Abecedarian_CLF/article/details/83502477