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

通过前两篇博客Fiddler教程HTTP协议详解,我们了解了Web的原理.

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

源代码下载

运行后效果如下

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

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

C#_自动化测试1_模拟post,get_12306火车票网站自动登录工具的更多相关文章

  1. C#_自动化测试3_controll IE

    目前市面上有很多Web UI自动化测试框架,比如WatiN, Selinimu,WebDriver,还有VS2010中的Coded UI等等.  这些框架都可以操作Web中的控件,模拟用户输入,点击等 ...

  2. C#_自动化测试 (四) 自动卸载软件

    在平常的测试工作中,经常要安装软件,卸载软件,  即繁琐又累.  安装和卸载完全可以做成自动化. 安装软件我们可以通过自动化框架,自动点击Next,来自动安装.  卸载软件我们可以通过msiexec命 ...

  3. js_html_input中autocomplete="off"在chrom中失效的解决办法 使用JS模拟锚点跳转 js如何获取url参数 C#模拟httpwebrequest请求_向服务器模拟cookie发送 实习期学到的技术(一) LinqPad的变量比较功能 ASP.NET EF 使用LinqPad 快速学习Linq

    js_html_input中autocomplete="off"在chrom中失效的解决办法 分享网上的2种办法: 1-可以在不需要默认填写的input框中设置 autocompl ...

  4. 利用phantomjs模拟QQ自动登录

    之前为了抓取兴趣部落里的数据,研究了下QQ自动登录. 当时搜索了一番,发现大部分方法都已经失效了,于是准备自己开搞. 第一个想到的就是参考网上已有方案的做法,梳理登陆js的实现,通过其他语言重写.考虑 ...

  5. 爬虫模拟cookie自动登录(人人网自动登录)

    什么是cookie? 在网站中,HTTP请求时无状态的,也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是谁,cookie的出现就是为了解决这个问题,第一次登陆后服 ...

  6. QQ模拟自动登录实现

    QQ模拟自动登录实现 本篇文章主要介绍"QQ模拟自动登录实现(带验证码)",主要涉及到java 实现QQ自动登录(带验证码)方面的内容,对于java 实现QQ自动登录(带验证码)感 ...

  7. casperjs配合phantomjs实现自动登录百度,模拟点击等等操作 - 怕虎在线www.ipahoo.com图文教程 - 怕虎在线

    微信支付取消2万元保证金门槛,这是全民电商来袭!-观点-虎嗅网 微信支付取消2万元保证金门槛,这是全民电商来袭! casperjs配合phantomjs实现自动登录百度,模拟点击等等操作 - 怕虎在线 ...

  8. C#模拟网站用户登录

    我们在写灌水机器人.抓资源机器人和Web网游辅助工具的时候第一步要实现的就是用户登录.那么怎么用C#来模拟一个用户的登录拉?要实现用户的登录,那么首先就必须要了解一般网站中是怎么判断用户是否登录的. ...

  9. Mysql优化_慢查询开启说明及Mysql慢查询分析工具mysqldumpslow用法讲解

    Mysql优化_慢查询开启说明及Mysql慢查询分析工具mysqldumpslow用法讲解   Mysql慢查询开启 Mysql的查询讯日志是Mysql提供的一种日志记录,它用来记录在Mysql中响应 ...

随机推荐

  1. duilib中控件拖拽功能的实现方法(附源码)

    转载请说明原出处,谢谢~~:http://blog.csdn.net/zhuhongshu/article/details/41144283 duilib库中原本没有显示的对控件增加拖拽的功能,而实际 ...

  2. 【windows核心编程】一个API拦截的例子

    API拦截 修改PE文件导入段中的导入函数地址 为 新的函数地址 这涉及PE文件格式中的导入表和IAT,PE文件中每个隐式链接的DLL对应一个IMAGE_IMPORT_DESCRIPTOR描述符结构, ...

  3. TRANSLATE

    语法格式: TRANSLATE(expr, from_string, to_string) 示例如下: SELECT TRANSLATE('ab 你好 bcdefg', 'abcdefg', '123 ...

  4. CentOS下编译安装hping3

    安装hping之前,先装上libpcap-dev和tcl-dev 1.获取源码包 wget http://www.hping.org/hping3-20051105.tar.gz 2.解压,得到 hp ...

  5. Azure支持docker简介以及使用指南

    Docker 是一个开源的项目,主要的特点是能将应用程序包装在一个 LXC (Linux Container) 容器中,当这些应用被包装进容器后,部署.迁移都变得更为简单.与传统的虚拟化技术相比,虚拟 ...

  6. crontab 定时任务格式

    如下内容节选自<Linux Crontab 定时任务 命令详解> 用crontab -e 添加要执行的命令 添加的命令必须以如下格式: * * * * * /command path 前五 ...

  7. JDBC学习笔记(9)——DBUtils的使用

    使用DBUtils提供的功能需要使用commons-dbutils-1.6.jar这个JAR包,在Apache官网可以下载到 使用DBUtils进行更新操 测试QueryRunner类的update方 ...

  8. Oracle中纵横表的转化

    横表就是普通的建表方式,如一个表结构为:主键.字段1.字段2.字段3......如果变成纵表后, 则表结构为:主键.字段代码.字段值.而字段代码则为字段1.字段2.字段3. 纵表对从数据库到内存的映射 ...

  9. poj 1915 http://poj.org/problem?id=1915

    /**< */#include <stdio.h> #include <string.h> #include <stdlib.h> #include < ...

  10. hdu 4496 (并差集)

    题意:给出一个图,m条边,输出删除前i条边后该图的联通块的个数. 思路:刚开始想着是不是联通问题,后来看明白题意后知道,如果从最后一条边添加的话,答案就会出来了,就是并差集的操作. #include& ...