如何用httpWebRequest模拟网页登录QQ邮箱

labilaoxin 2011-05-30 07:23:01
尝试用c#写一个模拟网页登录QQ邮箱的工具。
但是用Fiddler监视发现,qq邮箱登录不是POST的。
尝试用截取的登录链接request,登录失败。

希望得到高手指教!
...全文
3180 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
csdhd 2011-11-03
  • 打赏
  • 举报
回复
不好办,PM我,共同研究
  • 打赏
  • 举报
回复
哎, 以前哥也尝试过, 可惜搞不定。
longbin891012 2011-08-08
  • 打赏
  • 举报
回复
try
{
foreach (string key in stringDict.Keys)
{
string formitem = string.Format(stringKeyHeader, key, stringDict[key]);
byte[] formitembytes = Encoding.GetEncoding("gb18030").GetBytes(formitem);
memStream.Write(formitembytes, 0, formitembytes.Length);
}

// 写入最后的结束边界符
memStream.Write(endBoundary, 0, endBoundary.Length);
webRequest.ContentLength = memStream.Length;
webRequest.CookieContainer = Portal.gc.EmailCookie;

var requestStream = webRequest.GetRequestStream();

memStream.Position = 0;
var tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();

requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();

var httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
using (var httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(),
Encoding.GetEncoding("gb18030")))
{
responseContent = httpStreamReader.ReadToEnd();
}

//fileStream.Close();
httpWebResponse.Close();
webRequest.Abort();
}
catch (Exception ex)
{
LogHelper.Error(ex);
}

return responseContent;
}
error 2011-07-16
  • 打赏
  • 举报
回复
过程很简单,抓包,分析,提交 至于代码,注意参数加密和cookie.实在不行找我吧
sugarbelle 2011-06-18
  • 打赏
  • 举报
回复
我想知道答案.帮顶.
labilaoxin 2011-06-18
  • 打赏
  • 举报
回复
楼上2位的,貌似都没给出登录的具体细节?
xiaoqiu1234 2011-06-18
  • 打赏
  • 举报
回复
string id32 = "";
string id32Value = "";
private void GetCanSendMailQun()
{
//引用地址
string refUrl = string.Format("http://m411.mail.qq.com/cgi-bin/frame_html?sid={0}&r={1}", Portal.gc.LoginInfo.SID, Portal.gc.LoginInfo.R);
//可发送邮件的群列表信息
string url = string.Format("http://m411.mail.qq.com/cgi-bin/grouplist?sid={0}&t=compose_group&gid=&s=from_mail_list", Portal.gc.LoginInfo.SID);

httpHelper.Encoding = Encoding.GetEncoding("gb18030");
string content = httpHelper.GetHtml(url, Portal.gc.EmailCookie, refUrl);
//获取群列表并解析
string itemRegex = "<option\\s*id=\"(?<gname>.*?)\"\\s*value=\"(?<gid>.*?)\"\\s*>\\s*(?<name>.*?)\\s*</option>";
Regex re = new Regex(itemRegex, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);
Match mc = re.Match(content);
if (mc.Success)
{
MatchCollection mcs = re.Matches(content);
this.txtQunList.Items.Clear();
foreach (Match me in mcs)
{
string strName = me.Groups["name"].Value;
string strEmail = me.Groups["gid"].Value;
CListItem item = new CListItem(strName, strEmail);
this.txtQunList.Items.Add(item);
}
}

//取得一个动态构造的Hidden参数的名称和值,该参数名和值都是采用32位MD5编码,所以比较容易拿到
itemRegex ="<input\\s*id=\"(?<id>.{32})\"\\stype=\"hidden\"\\s*name=\"(?<name>.{32})\"\\s*value=\"(?<value>.{32})\"/>";
re = new Regex(itemRegex, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);
mc = re.Match(content);
if (mc.Success)
{
id32 = mc.Groups["id"].Value;
id32Value = mc.Groups["value"].Value;
}
}

以上操作就是获取群列表的功能代码,剩下的我们继续跟踪如何发送群邮箱的,发送群邮件的操作和一般的POST方式不同,他是采用了一种特别的方式进行处理,也就是发送MultiPart内容方式。下面我发送了一份宣传的邮件,监测到提交的字符列表如下所示:


发送邮件的代码如下所示:

private void btnSendQunMail_Click(object sender, EventArgs e)

{
CListItem item = this.txtQunList.SelectedItem as CListItem;
if (item != null)
{
string refurl = string.Format("http://m411.mail.qq.com/cgi-bin/grouplist?sid={0}&t=compose_group&gid=&s=from_mail_list", Portal.gc.LoginInfo.SID);
string sendUrl = string.Format("http://m411.mail.qq.com/cgi-bin/groupmail_send?sid={0}", Portal.gc.LoginInfo.SID);

#region 构造邮件内容
NameValueCollection col = new NameValueCollection();
col.Add("sid", Portal.gc.LoginInfo.SID);
col.Add("actiontype", "send");
col.Add("bigattachcnt", "");
col.Add("priority", "");
col.Add("contenttype", "html");
col.Add("savesendbox", "");
col.Add("sendname", "alias");
col.Add("qqshow", "");
col.Add("fmailid", "");
col.Add("cattachelist", "");
col.Add("fattachlist", "");
col.Add("rsturl", "");
col.Add("fileidlist", "");
col.Add("verifykey", "");
col.Add("verifycode", "");
col.Add("verifycode_cn", "");
col.Add("t", "");
col.Add("s", "group");
col.Add("contenttext", "");
col.Add("hitaddrbook", "0");
col.Add("backurl", "");
col.Add("newwin", "");
col.Add("mailtype", "");
//col.Add("sid", Portal.gc.LoginInfo.SID);
col.Add(id32, id32Value);
col.Add("groupname", item.Text);
col.Add("qqgroupid", item.Value);
col.Add("subject", "给大家介绍一个营销好帮手,QQ搜通天企业版");
col.Add("votesubject", "");
//col.Add("option", "");
//col.Add("option", "");
col.Add("option", "");
col.Add("content__html", "<DIV><SPAN id=picture><A href=\"http://www.iqidi.com/Download/QQEnterprise1.png\"><IMG height=756 alt=QQ搜通天企业版 src=\"http://www.iqidi.com/Download/QQEnterprise1.png\" width=925 border=0></A></SPAN><BR></DIV>");

#endregion
string content = HttpPostData(sendUrl, col, refurl);
if (content.Contains("验证码错误"))
{
MessageUtil.ShowWarning("验证码错误");
}
}
}

其中HttpPostData关键函数就是封装发送MultiPart内容的代码,主要是组装各种键值的数据。

private static string HttpPostData(string url, NameValueCollection stringDict, string referer)
{
string responseContent = "";
var memStream = new MemoryStream();
var webRequest = (HttpWebRequest)WebRequest.Create(url);
// 边界符
var boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
// 边界符
var beginBoundary = Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
// 最后的结束符
var endBoundary = Encoding.ASCII.GetBytes("--" + boundary + "--\r\n");

// 设置属性
webRequest.Method = "POST";
webRequest.Accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*";
webRequest.Referer = referer;
webRequest.ContentType = "multipart/form-data; boundary=" + boundary;
webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET4.0C; .NET4.0E; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; InfoPath.2)";
//webRequest.Timeout = timeOut;

// 写入字符串的Key
var stringKeyHeader = "\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\"" +
"\r\n\r\n{1}\r\n";

try
{
foreach (string key in stringDict.Keys)
{
string formitem = string.Format(stringKeyHeader, key, stringDict[key]);
byte[] formitembytes = Encoding.GetEncoding("gb18030").GetBytes(formitem);
memStream.Write(formitembytes, 0, formitembytes.Length);
}

// 写入最后的结束边界符
memStream.Write(endBoundary, 0, endBoundary.Length);
webRequest.ContentLength = memStream.Length;
webRequest.CookieContainer = Portal.gc.EmailCookie;

var requestStream = webRequest.GetRequestStream();

memStream.Position = 0;
var tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();

requestStream.Write(tempBuffer, 0, tempBuffer.Length);
requestStream.Close();

var httpWebResponse = (HttpWebResponse)webRequest.GetResponse();
using (var httpStreamReader = new StreamReader(httpWebResponse.GetResponseStream(),
Encoding.GetEncoding("gb18030")))
{
responseContent = httpStreamReader.ReadToEnd();
}

//fileStream.Close();
httpWebResponse.Close();
webRequest.Abort();
}
catch (Exception ex)
{
LogHelper.Error(ex);
}

return responseContent;
}
labilaoxin 2011-06-17
  • 打赏
  • 举报
回复
扑捉到的http请求:

CONNECT mail.qq.com:443 HTTP/1.0
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
Proxy-Connection: Keep-Alive
Content-Length: 0
Host: mail.qq.com
Pragma: no-cache

The data sent represents an SSLv3-compatible ClientHello handshake. For your convenience, the data is extracted below.

Major Version: 3
Minor Version: 1
Random: 4D FB 6F 79 29 08 FB BB 00 FA F1 22 35 08 E5 79 23 BF CD 75 2E 8F 4E 24 46 6E E7 65 32 E7 7F 29
SessionID: 1C 34 D6 6A 2A 4B 69 44 C8 86 16 24 F6 8D E9 66 F2 A9 09 5E 6A 8C 7D 2B A8 36 39 1A 9A 7C BB C0
Ciphers:
[002F] TLS_RSA_AES_128_SHA
[0035] TLS_RSA_AES_256_SHA
[0005] SSL_RSA_WITH_RC4_128_SHA
[000A] SSL_RSA_WITH_3DES_EDE_SHA
[C013] TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA
[C014] TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA
[C009] TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
[C00A] TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
[0032] TLS_DHE_DSS_WITH_AES_128_SHA
[0038] TLS_DHE_DSS_WITH_AES_256_SHA
[0013] SSL_DHE_DSS_WITH_3DES_EDE_SHA
[0004] SSL_RSA_WITH_RC4_128_MD5



返回的数据:

HTTP/1.0 200 Blind-Connection Established
FiddlerGateway: Direct
StartTime: 23:15:05.570
EndTime: 23:15:05.869

This is a CONNECT tunnel, through which encrypted HTTPS traffic flows. To view the encrypted sessions inside this tunnel, ensure that the Tools > Fiddler Options > HTTPS > Decrypt HTTPS traffic option is checked.

The data sent represents an SSLv3-compatible ServerHello handshake. For your convenience, the data is extracted below.

Major Version: 3
Minor Version: 1
SessionID: 70 94 63 2C 55 DA 70 0F 86 5D 71 A9 2B 43 37 5B 42 50 0D 1D 47 99 96 12 DE 8A 8C 08 81 C0 91 DF
Random: 4D FB 6F EE AC 7E 26 F8 A0 57 0D C9 07 D3 62 57 54 FD 0E F7 18 02 F6 3C 77 A9 30 1E 9B 7E 1F C3
Cipher: 0x35



请问一下,这类请求如何用 httpwebrequest来发送???
andyqq8 2011-06-03
  • 打赏
  • 举报
回复
QQ邮箱密码也有加密函数的。要先解决加密函数再考虑用webrequest模拟。参考我这个:

http://topic.csdn.net/u/20110603/21/7349a6ec-fae4-4940-9233-202cd4760f2f.html?90085
porschev 2011-06-03
  • 打赏
  • 举报
回复

LZ现在提交是什么错?

如果没验证码。、、

httpWebRequest的Method设为GET

就是一个httpWebRequest的get方式提交数据。。
liuyilin888 2011-06-03
  • 打赏
  • 举报
回复
高手都不弄这个
labilaoxin 2011-06-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 caozhy 的回复:]
有没有验证码?

没有的话基本都好搞。
[/Quote]

验证码时有时无
labilaoxin 2011-06-03
  • 打赏
  • 举报
回复
验证码可以手工验证,无所谓!
threenewbee 2011-05-31
  • 打赏
  • 举报
回复
有没有验证码?

没有的话基本都好搞。
labilaoxin 2011-05-31
  • 打赏
  • 举报
回复
没高手吗?

111,098

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧