51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

测试开发精英班,通向高级软件测试工程师【好消息】企业内训服务上线啦!项目为王,自动化测试提升加速器 !横扫BAT,Python全栈测试开发技能大全
【115期】:如何从测试工程师成长为测试开发? 参与调查问卷 缔造行业趋势 月薪15K+的测试开发必备技能? 【活动】为视频UP主打CALL,互动领福利!
查看: 2286|回复: 0

[转贴] Web自动化测试之12306火车票网站自动登录工具

[复制链接]
  • TA的每日心情

    3 天前
  • 签到天数: 508 天

    连续签到: 1 天

    [LV.9]测试副司令

    发表于 2016-4-8 13:39:10 | 显示全部楼层 |阅读模式

    还记得2011年春运,12306火车票预订网站经常崩溃无法登录吗。 今天我们就开发一个12306网站自动登录软件。 帮助您轻松订票

    Web的原理就是,浏览器发送一个Request给Web服务器,Web服务器处理完这个请求之后发送一个HTTP Response给浏览器。

    如果我们用自己写的程序来发送Request给Web服务器,然后再捕获Web服务器发回来的Response. 检查它与期望值值是否一致。 这不就是Web自动化测试吗? 这样的自动化测试叫做请求响应测试, 别小看这样的自动化测试。 什么开心农场助手,自动投票机。 网络爬虫都是用这个做的。

    阅读目录

    • .NET中提供的类来发送HTTP Request
    • WebClient类的用法
    • 模拟“GET” 方法
    • Cookie 的处理
    • 如何跟HTTPS的网站交互
    • 模拟"POST" 方法
    • 客户端发送给服务端的数据进行UrlEncode处理
    • 实例:12306火车票网站登录工具
    • 源代码下载

    .NET中提供的类来发送HTTP Request

    在System.Net命名工具下, .NET提供了5种方法 可以发送HTTP Request和取回HTTP Response. 它们分别是

    WebClient:

    WebRequent-WebResponse:

    HttpWebRequest-HttpWebResponse:

    TcpClient:

    Socket:

    这5个类中,最适合的就是HttpWebRequest-HttpWebResponse了, 这个才能满足我们需要的功能。 顺便说下WebClient类的用法

    WebClient类的用法

    WebClient的用法极其简单, 主要用于下载文件,或者单纯获取Response. 这个类不能模拟“POST” 的Http Request, 功能很少。

    实例如下:

    static void Main(string[] args)        {            // 博客园首页地址            string uri = "http://www.cnblogs.com";            WebClient MyWebClient = new WebClient();            Stream st = MyWebClient.OpenRead(uri);            StreamReader sr = new StreamReader(st);            string html = sr.ReadToEnd();            sr.Close();            st.Close();            Console.Write(html);        }

    模拟“GET” 方法

    我们主要是使用HttpWebRequest-HttpWebResponse 这两个类来做自动化测试.

    先看看如何模拟“GET”方法,来打开博客园首页, 在下面的例子中,设置了一些 HttpWebRequest的一些属性

    static void Main(string[] args)        {            // 博客园首页地址            string uri = "http://www.cnblogs.com";            HttpWebRequest Req = (HttpWebRequest)WebRequest.Create(uri);            // 浏览器和服务器交互的方法            Req.Method = "GET";            // 浏览器的类型,IE或者Firefox            Req.UserAgent = "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1;)";            // 是否允许自动重定向(自动跳转)            Req.AllowAutoRedirect = true;            // 自动跳转的次数            Req.MaximumAutomaticRedirections = 3;            // 超时时间50000=50秒            Req.Timeout = 50000;            //  是否建立TCP持久连接            Req.KeepAlive = true;            HttpWebResponse response = (HttpWebResponse)Req.GetResponse();            Stream stream = response.GetResponseStream();            Encoding myEncoding = Encoding.GetEncoding("UTF-8");            StreamReader streamReader = new StreamReader(stream, myEncoding);            string html = streamReader.ReadToEnd();            Console.Write(html);        }

    Cookie 的处理

    还有一个很重要的问题是,我们如何处理Cookie? 程序和Web服务器的交互中, 程序需要把Cookie发送给Web服务器, Web服务器也会给程序发送新的Cookie. 我们怎么模拟这个呢?

    C#提供了 CookieContainer 对象。 HttpWebRequest发送Request时会使用CookieContainer 中的Cookie. HttpWebResponse返回Response后,会自动修改CookieContainer 对象的Cookie. 这样的话,Cookie就不用我们操心了。 用法非常简单

               CookieContainer MyCookieContainer = new CookieContainer();                                    HttpWebRequest Req = (HttpWebRequest)WebRequest.Create(uri);                                    Req.CookieContainer = MyCookieContainer;

    如何跟HTTPS的网站交互

    我们用浏览器打开HTTPS的网站,如果我们没有安装证书,通常页面会显示 "此网站的安全证书有问题",我们必须再次点"继续浏览此网站(不推荐)"才能查看页面信息. 如下图所示

    那么我们的程序,如何忽略HTTPS证书错误呢?

    只要在程序中加入下面这段代码,就可以忽略HTTPS证书错误,让我们的程序能和HTTPS网站正确的交互了.

                    System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) =>                {                                                    return true;                                                 };

    模拟"POST" 方法

    POST和GET的区别在于, POST会把数据放在Body里面发送给Web服务器. 代码如下

    View Code         public static string GetResponse(string url, string method, string data)        {            try            {                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);                req.KeepAlive = true;                req.Method = method.ToUpper();                req.AllowAutoRedirect = true;                req.CookieContainer = CookieContainers;                req.ContentType = "application/x-www-form-urlencoded";                req.UserAgent = IE7;                req.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";                req.Timeout = 50000;                if (method.ToUpper() == "POST" && data != null)                {                    ASCIIEncoding encoding = new ASCIIEncoding();                    byte[] postBytes = encoding.GetBytes(data); ;                    req.ContentLength = postBytes.Length;                    Stream st = req.GetRequestStream();                    st.Write(postBytes, 0, postBytes.Length);                    st.Close();                }                System.Net.ServicePointManager.ServerCertificateValidationCallback += (se, cert, chain, sslerror) =>                {                    return true;                };                Encoding myEncoding = Encoding.GetEncoding("UTF-8");                HttpWebResponse res = (HttpWebResponse)req.GetResponse();                Stream resst = res.GetResponseStream();                StreamReader sr = new StreamReader(resst, myEncoding);                string str = sr.ReadToEnd();                return str;            }            catch (Exception)            {                return string.Empty;            }        }

    客户端发送给服务端的数据进行UrlEncode处理

    需要注意的是Web客户端发给Web服务端的数据如果包含空格和特殊字符(比如:汉字) 就要进行UrlEncode处理。

    解决这个问题很简单。

    在C#中Add reference 添加System.Web 组件

    添加System.Web命名空间, 然后调用HttpUtility.UrlEncode()方法就可以进行编码了

    实例:12306火车票网站登录工具

    2011年铁道部推出了12306火车票预订网站, 可是因为访问者太多,经常崩溃。根本登录不了。网站访问高峰的时候,根本没办法登录成功, 一直会报错(如下图)

    下面我们就运用上面的知识,来开发一个自动登录的工具

    首先我们用浏览器去打开12306网站去登录, 同时打开Fiddler去抓包分析,看看浏览器是如何和Web服务器交互的。

    通过抓包分析,我们发现登录其实很简单。就是把用户名,密码和验证码通过"POST"方法提交给服务器。如下图所示

    在Fiddler中我们点击Inspectors tab->TextView Tab下, 能看到提交给Web服务器的数据是

    string data="loginUser.user_name=thisisuserName&nameErrorFocus=&user.password=thispassword&passwordErrorFocus=&randCode=CF99&randErrorFocus=";

    我们把用户名,密码,验证码换成变量,然后Post给Web服务器就可以了。

    登录的时候需要输入验证码。 很幸运的是12306网站在这里有个bug, 当验证码图片没有主动刷新的时候,老的验证码一直可以用。 这样的话我们的工具用老的验证码不停地给服务器发送登录的HttpRequest,直到登录成功。

    登录的核心代码如下, 实际的代码比这个复杂,要写成循环调用,还要写成多线程,完整的请参考源代码

    具体代码为

    string data = "loginUser.user_name=" + userName + "&nameErrorFocus=&user.password=" + password               + "&passwordErrorFocus=&randCode=" + code + "&randErrorFocus=focus";string loginUrl = "https://dynamic.12306.cn/otsweb/loginAction.do?method=login";string afterLogin = HttpHelper.GetResponse(loginUrl, "POST", data);

    源代码下载

    运行后效果如下

    完整的代码请点此链接: 12306火车票预订网站自动登录工具 请用VS2008打开

    过段时间再写篇博客, 我将介绍12306火车票自动预订工具的开发过程。 此工具可以自动登录,自动下单。 买火车票就是小case了。



    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2020-10-25 16:42 , Processed in 0.066093 second(s), 28 queries .

    Powered by Discuz! X3.2

    © 2001-2020 Comsenz Inc.

    快速回复 返回顶部 返回列表