C# 实现模拟登录功能,实现公共类分享。
前言
最近在研究模拟登录的各种方法, 主要想要实现的两个功能是:
1.点击按钮可以直接跳转并登录到某一个系统中。
2.抓取某一个系统中某一个页面中的特定数据。
为此在网上查了许多的资料,首先了解到自身对http协议基础知识的欠缺,初步了解后,明白想要实现模拟登录首先要学会抓包这一项基本的技能,关于抓包这里就不详细介绍了,向大家推荐一款软件fiddler,一款不错的抓包软件。
首先客户端向服务端请求无非两种类型get或post,所以我们要了解在登录某一个系统时post的地址,以及需要post的参数。这些都需要通过抓包来获取。
一、简单的表单提交
第一种功能跳转就是简单的表单的提交,所有系统的登录都是表单的post提交,所以只需要在html中模拟写出该系统的表单需要提交的参数并赋值,提交表单即可跳转。
/// <summary>
///返回html表单
///action post地址,postDict键值对
/// <summary>
public string getPostFormHtml(HJFormModel model)
{
string action = model.action;
Dictionary<string, string> postDict = model.postDict;
StringBuilder sb = new StringBuilder();
sb.Append("<form method=\"post\" id=\"myHttpForm\" action=\"" + action + "\">");
sb.Append(" <div>");
sb.Append(" <br />");
foreach (var dic in postDict)
{
sb.Append(" <input type=\"hidden\" name=\"" + dic.Key + "\" value=\"" + dic.Value + "\" />");
}
sb.Append(" <input type=\"submit\" value=\"登录\" />");
sb.Append(" </div>");
sb.Append(" </form>");
return sb.ToString();
}
/// <summary>
/// Form表单生成请求参考类
/// </summary>
public class HJFormModel
{ /// <summary>
/// 表单提交地址
/// </summary>
public string action { get; set; }
/// <summary>
/// 需要提交的数据参数
/// </summary>
public Dictionary<string, string> postDict { get; set; }
}
上面是代码下面是请求类,就是从后台返回html,生成一个表单,提交即可,其中postDict 指需要提交的参数这里由键值对来赋值,如遇到需要输入验证码的登录那么就需要增加一条验证码连接的图片,人工识别填写(目前没有想到更好的方法)。
二、模拟登录抓取页面数据
第二种功能抓取页面的特定数据,其实就是获取某一页面所以的html,顺序一样首先要登录到系统中,下面附上公共类的代码。
/// <summary>
///根据参数,返回指定内容
/// <summary>
public HJHttpResult GetHtml(HJHttpItem Item)
{
HJHttpResult res = new HJHttpResult();
try
{
string htmldate;
string html;
CookieCollection cook = new CookieCollection();
cook = getCook(Item.GetCookieUrl, Item.Domain, Item.CookName);
if (!string.IsNullOrWhiteSpace(Item.postStingData))
{
postCookLogin(Item.PostUrl, cook, Item.postStingData);
}
else
{
postCookLogin(Item.PostUrl, cook, Item.postKeyData);
}
html = getAllHtml(Item.GetHtmlUrl, cook);
if (!string.IsNullOrWhiteSpace(html))
{
htmldate = getCutOutHtml(Item.beginString, Item.finishString, html);
}
else
{
htmldate = "获取失败";
}
res.html = htmldate;
res.CookieCoken = cook;
return res;
}
catch (Exception ex)
{
res.html = "获取失败" + ex.Message;
return res;
}
} /// <summary>
/// 已登录成功根据Cookie查询其他特定HTML
/// <summary>
public string GetUrlHtml(string beginString, string finishString, string Url, CookieCollection curCookies)
{
string html;
try
{
string AllHtml = getAllHtml(Url, curCookies);
html = getCutOutHtml(beginString, finishString, AllHtml);
return html;
}
catch (Exception ex)
{
html = "获取失败,请重新Post登录" + ex.Message;
return html;
}
}
/// <summary>
///截取html中特定的数据,beginString起始,finishString结束,html
/// <summary>
public string getCutOutHtml(string beginString, string finishString, string html)
{
int a = beginString.Length;
int i = html.IndexOf(beginString) + a;
int j = html.IndexOf(finishString);
return html.Substring(i, j - i);
} /// <summary>
///获取cookie
///url 获取地址,Domain Cook中的Domain,有哪些CookName
/// <summary>
public CookieCollection getCook(string Url, string Domain, string[] CookName)
{
CookieCollection curCookies = new CookieCollection(); HttpWebRequest reqget = (HttpWebRequest)WebRequest.Create(Url); reqget.CookieContainer = new CookieContainer();
reqget.CookieContainer.Add(curCookies); reqget.Method = "GET";
HttpWebResponse respget = (HttpWebResponse)reqget.GetResponse(); foreach (Cookie ck in respget.Cookies)
{
for (int i = ; i < CookName.Length; i++)
{
if (ck.Name == CookName[i])
{
Cookie cookget = new Cookie();
cookget.Value = ck.Value;
cookget.Name = ck.Name;
cookget.Domain = Domain;
curCookies.Add(cookget);
}
}
}
string DefaultUserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";
HttpWebRequest request = WebRequest.Create(Url) as HttpWebRequest;
request.Method = "GET";
request.UserAgent = DefaultUserAgent; request.CookieContainer = new CookieContainer();
request.CookieContainer.Add(curCookies); return curCookies;
} /// <summary>
///post登录
///Url post 地址 ,postdata POST数据(字符串),curCookies COOKIE
/// <summary>
public void postCookLogin(string Url, CookieCollection curCookies, string postData)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(Url);
//add cookie
req.CookieContainer = new CookieContainer();
req.CookieContainer.Add(curCookies);
//set to POST
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
//prepare post data
//string postDataStr = quoteParas(postDict);
byte[] postBytes = Encoding.UTF8.GetBytes(postData);
req.ContentLength = postBytes.Length; //send post data
Stream postDataStream = req.GetRequestStream();
postDataStream.Write(postBytes, , postBytes.Length);
postDataStream.Close(); //got response
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
string url = resp.ResponseUri.ToString(); //got returned html
StreamReader sr = new StreamReader(resp.GetResponseStream());
}
/// <summary>
///Url post 地址 ,postdata POST数据(键值对),curCookies COOKIE
/// <summary>
public void postCookLogin(string Url, CookieCollection curCookies, Dictionary<string, string> postData)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(Url);
//add cookie
req.CookieContainer = new CookieContainer();
req.CookieContainer.Add(curCookies);
//set to POST
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
//prepare post data
string postDataStr = quoteParas(postData);
byte[] postBytes = Encoding.UTF8.GetBytes(postDataStr);
req.ContentLength = postBytes.Length; //send post data
Stream postDataStream = req.GetRequestStream();
postDataStream.Write(postBytes, , postBytes.Length);
postDataStream.Close(); //got response
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
string url = resp.ResponseUri.ToString(); //got returned html
StreamReader sr = new StreamReader(resp.GetResponseStream());
} /// <summary>
///获取html页面
///cookCon 已登录成功的cook,Url 地址
/// <summary>
public string getAllHtml(string Url, CookieCollection curCookies)
{
CookieContainer cookCon = new CookieContainer();
cookCon.Add(curCookies);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(Url);
//属性配置
webRequest.AllowWriteStreamBuffering = true;
webRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
webRequest.MaximumResponseHeadersLength = -;
//webRequest.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";
webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "GET";
webRequest.Headers.Add("Accept-Language", "zh-cn");
webRequest.Headers.Add("Accept-Encoding", "gzip,deflate");
webRequest.KeepAlive = true;
webRequest.CookieContainer = cookCon;
try
{
//获取服务器返回的资源
using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
{
using (Stream sream = webResponse.GetResponseStream())
{
StreamReader streamReader = new StreamReader(sream);
string str = streamReader.ReadToEnd();
return str;
}
}
}
catch (WebException ex)
{
return "错误" + ex.Message;
}
}
/// <summary>
///get方式获取验证码
///Url验证码的地址,COOKie cookCon,savePath保存地址
/// <summary>
public bool boolDowloadCheckImg(string Url, CookieContainer cookCon, string savePath)
{
bool bol = true;
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(Url);
//属性配置
webRequest.AllowWriteStreamBuffering = true;
webRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
webRequest.MaximumResponseHeadersLength = -;
//webRequest.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";
webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Maxthon; .NET CLR 1.1.4322)";
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "GET";
webRequest.Headers.Add("Accept-Language", "zh-cn");
webRequest.Headers.Add("Accept-Encoding", "gzip,deflate");
webRequest.KeepAlive = true;
webRequest.CookieContainer = cookCon;
try
{
//获取服务器返回的资源
using (HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse())
{
using (Stream sream = webResponse.GetResponseStream())
{
List<byte> list = new List<byte>();
while (true)
{
int data = sream.ReadByte();
if (data == -)
break;
list.Add((byte)data);
}
File.WriteAllBytes(savePath, list.ToArray());
}
}
}
catch (WebException ex)
{
bol = false;
}
catch (Exception ex)
{
bol = false;
}
return bol;
} //quote the input dict values
//note: the return result for first para no '&'
/// <summary>
///键值对与字符流转换
/// <summary>
public string quoteParas(Dictionary<string, string> paras)
{
string quotedParas = "";
bool isFirst = true;
string val = "";
foreach (string para in paras.Keys)
{
if (paras.TryGetValue(para, out val))
{
if (isFirst)
{
isFirst = false;
quotedParas += para + "=" + HttpUtility.UrlPathEncode(val);
}
else
{
quotedParas += "&" + para + "=" + HttpUtility.UrlPathEncode(val);
}
}
else
{
break;
}
} return quotedParas;
} }
/// <summary>
/// Http请求参考类
/// </summary>
public class HJHttpItem
{
/// <summary>
/// 获得Cookie的URL
/// </summary>
public string GetCookieUrl { get; set; }
/// <summary>
/// Cookie的Domain
/// </summary>
public string Domain { get; set; }
/// <summary>
/// 截取Html的起始位置
/// </summary>
public string beginString { get; set; }
/// <summary>
/// 截取Html的终止位置
/// </summary>
public string finishString { get; set; }
/// <summary>
/// Cookie的Name集合{"",""}
/// </summary>
public string[] CookName { get; set; }
/// <summary>
/// post的数据字符串格式 注:与postKeyData必须有一个不是为空的
/// </summary>
public string postStingData { get; set; }
/// <summary>
/// post的数据键值对格式 注:与postStingData必须有一个不是为空的
/// </summary>
public Dictionary<string, string> postKeyData { get; set; }
/// <summary>
/// post的地址
/// </summary>
public string PostUrl { get; set; }
/// <summary>
/// 获取Html的地址
/// </summary>
public string GetHtmlUrl { get; set; }
}
/// <summary>
/// Http返回参数类
/// </summary>
public class HJHttpResult
{ /// <summary>
/// 返回的Html数据
/// </summary>
public string html { get; set; }
/// <summary>
/// 返回的Cookie数据
/// </summary>
public CookieCollection CookieCoken { get; set; }
}
大致原理为,首先获取相应登录系统的Cookie,这里我们要理解一下Cookie中SessionID的用处,SessionID由服务端向客户端发起,每次打开浏览器会更新SessionID,SessionID的目的是为了存贮post提交后登录状态的信息,如登录的用户,这个由系统而定,获得Cookie后利用这个Cookie和postdata向post地址提交,这时如果登录成功SessionID就记录下该账号的登录状态,此时利用SessionID访问该域下的其他页面就可以了,获取下来html截取下来想要的数据,同样有需要验证码的get方法获取验证码,人工识别输入post登录。
三、小结
最近在这方面做了一些小研究,遇到的问题还有很多,比如如何从后台登录成功后可以跳转到浏览器中并保持登录状态,而且我做测试的用的都是一些较为简单的系统,需要的参数并不复杂,如果哪位大神对这方面有着较深的研究,或者有这方面比较完善的系统可以分享,欢迎指出思路或其他有错误的地方,感激不尽。
C# 实现模拟登录功能,实现公共类分享。的更多相关文章
- PHP简单模拟登录功能实例分享
1.curl实现模拟登录的代码,(只是实现服务器与服务器建立会话,其实并没有在客户端与服务器之间建立会话) <?php $cookie_jar = tempnam('./tmp','cookie ...
- 测试开发Python培训:模拟登录新浪微博-技术篇
测试开发Python培训:模拟登录新浪微博-技术篇 一般一个初学者项目的起点就是登陆功能的自动化,而面临的项目不同实现的技术难度是不一样的,poptest在做测试开发培训中更加关注技术难点,掌握技 ...
- HttpWebRequest 模拟登录响应点击事件(分享自己用的HttpHelper类)
平时也经常采集网站数据,也做模拟登录,但一般都是html控件POST到页面登录:还没有遇到用户服务器控件button按钮点击事件登录的,今天像往常一样POST传递参数,但怎么都能登录不了:最后发现还有 ...
- 模拟登录神器之PHP基于cURL实现自动模拟登录类
一.构思 从Firefox浏览器拷贝cURL命令(初始页.提交.提交后) 自动分析curl形成模拟登录代码 默认参数:ssl/302/gzip 二.实现 接口 (一)根据curl信息执行并解析结果 p ...
- Android+struts2+json方式模拟手机登录功能
涉及到的知识点: 1.Struts2框架的搭建(包括Struts2的jSON插件) 2.Android前台访问Web采用HttpClient方式. 3.Android采用JSON的解析. 服务端主要包 ...
- 用java集合模拟登录和注册功能
package com.linkage.login; import java.util.HashMap;import java.util.Iterator;import java.util.Map;i ...
- 用java数组模拟登录和注册功能
package com.linkage.login; import java.util.Scanner; public class user { // 存储用户名和密码 public static S ...
- HttpClient + Jsoup模拟登录教务处并获取课表
1.概述 最近想做一个校园助手类的APP,由于第一次做,所以打算先把每个功能单独实现,防止乱了阵脚.利用教务处登录获取课表和成绩等是一个基本功能,所以以获取课表为例实现了这个功能.完整代码点这里,尝试 ...
- javamail模拟邮箱功能发送电子邮件-中级实战篇【新增附件发送方法】(javamail API电子邮件实例)
引言: JavaMail jar包下载地址:http://java.sun.com/products/javamail/downloads/index.html 此篇是紧随上篇文章而封装出来的,阅读本 ...
随机推荐
- 基于Spring4的定时任务管理
在项目中,有时会遇到定时任务的处理,下面介绍一下我的做法. 此做法基于Spring4,Spring框架搭建成功,另需引入quartz.jar,pom.xml文件中加入 <dependency&g ...
- Python学习记录----语法学习
一控制语句 http://blog.csdn.net/lynn_yan/article/details/5464911 if 语句 二 字典详解 http://blog.csdn.net/moodyt ...
- TCP/IP协议之IP层
TCP/IP协议的结构参见下图.有应用层,运输层,网络层,链路层. 但是如果更细化的话,其实还有几层没在这上面体现出来. 1 表示层:数据格式化,代码转换,加密. 没有协议 2 会话层:解除或者建立与 ...
- 初学者:浅谈web前端就业的学习路线
初级前端 主要学习三个部分:HTML,CSS,JavaScript 一.html + css部分: 这部分特别简单,到网上搜资料,书籍视频非常多.css中盒子模型,流动,block,inline,层叠 ...
- 准备 overlay 网络实验环境 - 每天5分钟玩转 Docker 容器技术(49)
为支持容器跨主机通信,Docker 提供了 overlay driver,使用户可以创建基于 VxLAN 的 overlay 网络.VxLAN 可将二层数据封装到 UDP 进行传输,VxLAN 提供与 ...
- Hibernate批量操作(一)
在项目的开发过程之中,我们常会遇到数据的批量处理问题.在持久层采用Hibernate框架时,在进行批量操作时,需要考虑Hibernate实现机制带来的一些问题. 我们知道在每个Hibernate Se ...
- java大数常用的方法
创建大数对象: BigInteger a=new BigInteger("123"); BigInteger a=BigInteger.valueOf(); 常用方法: multi ...
- NYOJ 69 数的长度(数学)
数的长度 时间限制:3000 ms | 内存限制:65535 KB 难度:1 描述 N!阶乘是一个非常大的数,大家都知道计算公式是N!=N*(N-1)······*2*1.现在你的任务是计算出 ...
- NYOJ 23.取石子(一)
取石子(一) 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 一天,TT在寝室闲着无聊,和同寝的人玩起了取石子游戏,而由于条件有限,他/她们是用旺仔小馒头当作石子.游 ...
- macOS下加载动态库dylib报"code signature invalid"错误的解决办法
一.现象描述 在macOS上搞开发也有一段时间了,也积攒了一定的经验.然而,今天在替换工程中的一个动态库时还是碰到了一个问题.原来工程中用的是一个静态库,调试时发现有问题就把它替换成了动态库.这本来没 ...