自动化测试实战(一)12306火车票网站自动登录工具

news2024/11/28 5:39:45

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

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

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

阅读目录

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

.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服务器. 代码如下

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

源代码下载

运行后效果如下

 

 

完整的代码请留言

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/590505.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mybatis源码细节探究:MappedStatement和Cache对象对照关系研究

给自己的每日一句 不从恶人的计谋,不站罪人的道路,不坐亵慢人的座位,惟喜爱耶和华的律法,昼夜思想,这人便为有福!他要像一棵树栽在溪水旁,按时候结果子,叶子也不枯干。凡他所做的尽…

《面试1v1》类加载过程

我是 javapub,一名 Markdown 程序员从👨‍💻,八股文种子选手。 面试官: 你了解Java的类加载过程吗?跟我聊聊classes是如何加载到JVM中的。 候选人: Java的类加载过程由加载、验证、准备、解析和初始化5个…

5月底了,现在不想着跳槽可就晚了

前两天跟朋友感慨,今年的铜三铁四、裁员、疫情导致好多人都没拿到offer!现在已经5月底了,具体金九银十只剩下三个月。 对于想跳槽的职场人来说,绝对要从现在开始做准备了。这时候,很多高薪技术岗、管理岗的缺口和市场需求也出来了…

五、常用提升物体的方式

机器人在运动中伸展和提升功能,历来是比赛中机器人的一个重要的性能指标,因为按 比赛要求,机器人在上场前必须经过体积大小的检测,而在场地中如果能够有更好的伸展性 能将对比赛成绩十分有利,因此机器人提升自身高度以…

SAP-MM发票校验容差详解

MIRO发票校验容差详解 MIRO发票校验容差是指收货业务与发票校验业务之间的差异,这种差异可 能是物料价格差异、收货数量差异、收货金额差异等等,总之,发票校验的容差 内容最为丰富,容差类型有很多种,如下表所示&…

【ChatGPT插件第一期】28个ChatGPT插件,让你的学习、工作、生活效率翻倍!

文章目录 人工智能福利文章什么是ChatGPT插件如何使用ChatGPT插件28个插件全解读写在最后 人工智能福利文章 【分享几个国内免费可用的ChatGPT镜像】【10几个类ChatGPT国内AI大模型】【用《文心一言》1分钟写一篇博客简直yyds】【用讯飞星火大模型1分钟写一个精美的PPT】 Cha…

Linux I2C驱动分析4 - GPIO模拟I2C

一. 前言 在嵌入式开发中,由于芯片的I2C接口有限,或者出于硬件画板的方便,我们都需要将普通的GPIO模拟I2C接口使用。出于对这样的需求,Linux-2.6.x已经有相关代码了,Linux-3.x有标准的内核选项支持该功能,内…

模特信息管理系统的开发与实现(ASP.NET,SQLServer)

需求分析 模特信息管理系统主要给商家和模特用户提供服务,系统分为前台和后台两部分。 本研究课题重点主要包括:活动管理,商家管理,模特管理,系统公告管理和活动报名管理。 活动管理模块主要实现活动更新、活动添加、活…

生鲜农产品冷链物流配送路径优化模型构建及算法实现

摘要:本案例讲述的案例为生鲜农产品冷链物流配送路径优化,涉及的目标函数成本包括碳排放成本、固定成本、运输成本、货损变质成本、时间惩罚成本。 目标种类:单目标模型。 求解方法:基础版蚁群算法改进版蚁群算法。 整体对标层…

快速掌握EasyExcel在web场景中的应用(读和写)

目录 一、引入依赖 二、设置表头 三、web下载模板 四、测试下载功能 五、复杂表头 六、写入数据 七、格式优化 7.1 日期自定义转换 7.2 列宽行高注解 八、动态表头 九、动态表格写入数据 一、引入依赖 <dependency><groupId>com.alibaba</groupId>…

Linux——生产者消费者模型和信号量

目录​​​​​​​ 基于BlockingQueue的生产者消费者模型 概念 条件变量的第二个参数的作用 锁的作用 生产者消费者模型的高效性 生产者而言&#xff0c;向blockqueue里面放置任务 消费者而言&#xff0c;从blockqueue里面拿取任务&#xff1a; 总结 完整代码(不含存储…

从零开始搭建一个moveit2简单机械臂模型

文章目录 前言一、设计一个简单机械臂二、构造创建文件关系CMakeLists.txt 修改增加如下&#xff1a;package.xml 修改增加如下&#xff1a;urdf.rviz 全文如下&#xff1a;demo.launch.py 全文如下&#xff1a; launch rviz构造link构造joint 总结 前言 在网上搜了许多文章&a…

游戏互动,用Python点燃【儿童节】的欢乐!

当孩子们踏入人生的旅途时&#xff0c;他们需要的并不仅仅是学习知识&#xff0c;更需要的是在快乐的氛围中成长。六一儿童节即将来临&#xff0c;让我们用Python代码为孩子们送去一份特别的礼物吧&#xff01; 在本篇文章中&#xff0c;我会带领大家一起探索如何利用Python代…

php中文字符串提取方法,preg_replace 和preg_match_all区别

在php中&#xff0c;可以利用以下两种函数来只提取字符串的中文字符 preg_replace()函数 preg_match_all()函数 方法1&#xff1a;使用preg_match_all()函数 preg_match_all()函数配合正则表达式“/[\x{4e00}-\x{9fff}]/u”可以过滤字符串&#xff0c;只获取中文字符。 会…

chatgpt赋能python:Python中[:3]的用法介绍

Python中[:3]的用法介绍 Python是一种高级编程语言&#xff0c;经常被用于数据科学、机器学习、人工智能和Web应用程序开发。在Python中&#xff0c;有许多有用的编程技巧和语法&#xff0c;其中之一就是[:3]。 什么是[:3]&#xff1f; 在Python中&#xff0c;[:3]是一种称为…

研发工程师玩转Kubernetes——使用Ingress进行路由

依据微服务理念&#xff0c;我们希望每个独立的功能由一个服务支持。比如有两个接口&#xff1a;http://www.xxx.com/plus和http://www.xxx.com/minus&#xff0c;前者由一个叫plus-service的服务支持&#xff0c;后者由一个叫minus-service的服务支持。这样就需要一个路由层&a…

华为OD机试真题B卷 Java 实现【查找两个字符串a,b中的最长公共子串】,附详细解题思路

一、题目描述 查找两个字符串a,b中的最长公共子串。若有多个,输出在较短串中最先出现的那个。 注:子串的定义:将一个字符串删去前缀和后缀(也可以不删)形成的字符串。请和“子序列”的概念分开! 数据范围:字符串长度1≤length≤300 。 二、输入描述 输入两个字符串…

牛客网刷题学习SQL(五)

SQL25 查找山东大学或者性别为男生的信息 分析&#xff1a; 查看学校为山东大学或者性别为男性的用户的device_id、gender、age和gpa数据&#xff0c;结果不去重。 山东大学 --》 where university“山东大学” 男性—》where gender “male” 结果不去重 所以上面不能使用or&…

改进的yolo目标检测(yolo创新与改进)

目标检测是计算机视觉领域中的一个重要问题,它需要从图像或视频中检测出物体的位置和类别。近年来,深度学习技术在目标检测领域取得了显著的进展,其中一个重要的方法是基于YOLO(You Only Look Once)算法的目标检测。 YOLO算法的优点是速度快,但是在检测小物体和密集物体…

SAP-MM-发票-采购附加成本处理简介

一&#xff0e;采购附加成本处理&#xff1a; 原材料的采购成本包括采购成本&#xff08;采购单价*采购数量&#xff09;和相关采购附加成本&#xff08;运输费、保险费、报关费、仓储费、滞期费、租船费、码头费及代理费等费用&#xff09;&#xff0c;对于采购附加成本主要有…