C#中使用Post方式登录后得到如下的cookie world咖啡,请问是否正常

如何向某网址Post信息,并得到CookieContainer以便以后直接通过验证
你好,游客
如何向某网址Post信息,并得到CookieContainer以便以后直接通过验证
using S using System.N using System.IO; using System.T [STAThread] static void Main(string[] args) { &// &// TODO: 在此处添加代码以启动应用程序 &// &string url="http://localhost/csdn2/1.asp"; &//& &% &//& if request("aa")="zhuye" then session("ok")="ok" &//& if session("ok")="ok" then &//& response.write("登录") &//& else &//& response.write("没有登录") &//& end if &//& %& &string indata="aa=zhuye"; &string outdata=""; &CookieContainer myCookieContainer=new CookieContainer(); &//新建一个CookieContainer来存放Cookie集合 &HttpWebRequest myHttpWebRequest=(HttpWebRequest)WebRequest.Create(url); &//新建一个HttpWebRequest &myHttpWebRequest.ContentType="application/x-www-form-urlencoded"; &myHttpWebRequest.ContentLength=indata.L &myHttpWebRequest.Method="POST"; &myHttpWebRequest.CookieContainer=myCookieC &//设置HttpWebRequest的CookieContainer为刚才建立的那个myCookieContainer &Stream myRequestStream=myHttpWebRequest.GetRequestStream(); &StreamWriter myStreamWriter=new StreamWriter(myRequestStream,Encoding.GetEncoding("gb2312"));&&&&&&&&&&&&&&&& &myStreamWriter.Write(indata); &//把数据写入HttpWebRequest的Request流 &myStreamWriter.Close(); &myRequestStream.Close(); &//关闭打开对象 &HttpWebResponse myHttpWebResponse=(HttpWebResponse)myHttpWebRequest.GetResponse(); &//新建一个HttpWebResponse &myHttpWebResponse.Cookies=myCookieContainer.GetCookies(myHttpWebRequest.RequestUri); &//获取一个包含url的Cookie集合的CookieCollection &Stream myResponseStream=myHttpWebResponse.GetResponseStream(); &StreamReader myStreamReader=new StreamReader(myResponseStream,Encoding.GetEncoding("gb2312")); &outdata=myStreamReader.ReadToEnd(); &//把数据从HttpWebResponse的Response流中读出 &myStreamReader.Close(); &myResponseStream.Close(); &Console.WriteLine(outdata); &//显示"登录" &&//拿到了Cookie,再进行请求就能直接读取到登录后的内容了 &myHttpWebRequest=(HttpWebRequest)WebRequest.Create(url); &myHttpWebRequest.CookieContainer=myCookieC//* &//刚才那个CookieContainer已经存有了Cookie,把它附加到HttpWebRequest中则能直接通过验证 &myHttpWebResponse=(HttpWebResponse)myHttpWebRequest.GetResponse(); &myHttpWebResponse.Cookies=myCookieContainer.GetCookies(myHttpWebRequest.RequestUri);&&&&&&&&&&&& &myResponseStream=myHttpWebResponse.GetResponseStream(); &myStreamReader=new StreamReader(myResponseStream,Encoding.GetEncoding("gb2312")); &outdata=myStreamReader.ReadToEnd(); &myStreamReader.Close(); &myResponseStream.Close(); &Console.WriteLine(outdata);&&&& &//再次显示"登录" &//如果把*行注释调,就显示"没有登录" }
注释写得很明确了,不多罗嗦了。 补充:如果是以get方式登录的话,直接修改url就可以了,indate可以不写任何东西。(不要去修改myHttpWebRequest.Method为GET),比如把asp文件修改为if request.querystring("aa")="zhuye" then session("ok")="ok",只要修改url为string url="http://localhost/csdn2/1.asp?aa=zhuye";即可。
相关新闻 & & &
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款【教程】模拟登陆网站 之 C#版(内含两种版本的完整的可运行的代码)
之前已经介绍过了网络相关的一些基础知识了:
以及简单的网页内容抓取,用C#是如何实现的:
现在接着来介绍,以模拟登陆百度首页:
为例,说明如何通过C#模拟登陆网站。
不过,此处需要介绍一下此文前提:
假定你已经看完了:
了解了基本的网络相关基本概念;
知道了如何使用IE9的F12等工具去分析网页执行的过程。
1.模拟登陆网站之前,需要搞清楚,登陆该网站的内部执行逻辑
此想要通过程序,即C#代码,实现模拟登陆百度首页之前。
你自己本身先要搞懂,本身登陆该网站,内部的逻辑是什么样的。
而关于如何利用工具,分析出来,百度首页登录的内部逻辑过程,参见:
2.然后才是用对应的语言(C#)去实现,模拟登陆的逻辑
看懂了上述用F12分析出来的百度首页的登陆的内部逻辑过程,接下来,用C#代码去实现,相对来说,就不是很难了。
(1)关于在C#中如何利用cookie,不熟悉的,先去看:
(2)对于正则表达式不熟悉的,去参考:
(3)对C#中的正则表达式的类Regex,不熟悉的,可参考:
此处,再把分析出来的流程,贴出来,以便方便和代码对照:
     
     
     
发送的数据
     
需要获得/提取的返回的值
   
     
返回的cookie中的BAIDUID
包含BAIDUID这个cookie
从返回的html中提取出token的值
一堆的post data,其中token的值是之前提取出来的
需要验证返回的cookie中,是否包含BDUSS,PTOKEN,STOKEN,SAVEUSERID
然后,最终就可以写出相关的,用于演示模拟登录百度首页的C#代码了。
【版本1:C#实现模拟登陆百度首页的完整代码 之 精简版】
其中,通过UI中,点击“获取cookie BAIDUID”:
然后调用下面这部分代码:
private void btnGetBaiduid_Click(object sender, EventArgs e)
string baiduMainUrl = txbBaiduMainUrl.T
//generate http request
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baiduMainUrl);
//add follow code to handle cookies
req.CookieContainer = new CookieContainer();
req.CookieContainer.Add(curCookies);
req.Method = &GET&;
//use request to get response
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
txbGotBaiduid.Text = &&;
foreach (Cookie ck in resp.Cookies)
txbGotBaiduid.Text += &[& + ck.Name + &]=& + ck.V
if (ck.Name == &BAIDUID&)
gotCookieBaiduid =
if (gotCookieBaiduid)
//store cookies
curCookies = resp.C
MessageBox.Show(&错误:没有找到cookie BAIDUID !&);
获得上述所看到的BAIDUID这个cookie的值了。
然后接着点击“获取token值”,然后调用下面的代码:
private void btnGetToken_Click(object sender, EventArgs e)
if (gotCookieBaiduid)
string getapiUrl = &/v2/api/?getapi&class=login&tpl=mn&tangram=true&;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(getapiUrl);
//add previously got cookies
req.CookieContainer = new CookieContainer();
req.CookieContainer.Add(curCookies);
req.Method = &GET&;
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
string respHtml = sr.ReadToEnd();
//bdPass.api.params.login_token='5abe7fbbe1bfc267b90b3';
string tokenValP = @&bdPass\.api\.params\.login_token='(?&tokenVal&\w+)';&;
Match foundTokenVal = (new Regex(tokenValP)).Match(respHtml);
if (foundTokenVal.Success)
//extracted the token value
txbExtractedTokenVal.Text = foundTokenVal.Groups[&tokenVal&].V
extractTokenValueOK =
txbExtractedTokenVal.Text = &错误:没有找到token的值!&;
MessageBox.Show(&错误:之前没有正确获得Cookie:BAIDUID !&);
就可以获取对应的token的值了:
接着再去填上你的百度的用户名和密码,然后再点击“模拟登陆百度首页”,就会调用如下代码:
private void btnEmulateLoginBaidu_Click(object sender, EventArgs e)
if (gotCookieBaiduid && extractTokenValueOK)
string staticpage = &/cache/user/html/jump.html&;
//init post dict info
Dictionary&string, string& postDict = new Dictionary&string, string&();
//postDict.Add(&ppui_logintime&, &&);
postDict.Add(&charset&, &utf-8&);
//postDict.Add(&codestring&, &&);
postDict.Add(&token&, txbExtractedTokenVal.Text);
postDict.Add(&isPhone&, &false&);
postDict.Add(&index&, &0&);
//postDict.Add(&u&, &&);
//postDict.Add(&safeflg&, &0&);
postDict.Add(&staticpage&, staticpage);
postDict.Add(&loginType&, &1&);
postDict.Add(&tpl&, &mn&);
postDict.Add(&callback&, &parent.bdPass.api.login._postCallback&);
postDict.Add(&username&, txbBaiduUsername.Text);
postDict.Add(&password&, txbBaiduPassword.Text);
//postDict.Add(&verifycode&, &&);
postDict.Add(&mem_pass&, &on&);
string baiduMainLoginUrl = &/v2/api/?login&;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baiduMainLoginUrl);
//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(postDataStr);
req.ContentLength = postBytes.L
//send post data
Stream postDataStream = req.GetRequestStream();
postDataStream.Write(postBytes, 0, postBytes.Length);
postDataStream.Close();
//got response
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
//got returned html
StreamReader sr = new StreamReader(resp.GetResponseStream());
string loginBaiduRespHtml = sr.ReadToEnd();
//check whether got all expected cookies
Dictionary&string, bool& cookieCheckDict = new Dictionary&string, bool&();
string[] cookiesNameList = {&BDUSS&, &PTOKEN&, &STOKEN&, &SAVEUSERID&};
foreach (String cookieToCheck in cookiesNameList)
cookieCheckDict.Add(cookieToCheck, false);
foreach (Cookie singleCookie in resp.Cookies)
if (cookieCheckDict.ContainsKey(singleCookie.Name))
cookieCheckDict[singleCookie.Name] =
bool allCookiesFound =
foreach (bool foundCurCookie in cookieCheckDict.Values)
allCookiesFound = allCookiesFound && foundCurC
loginBaiduOk = allCookiesF
if (loginBaiduOk)
txbEmulateLoginResult.Text = &成功模拟登陆百度首页!&;
txbEmulateLoginResult.Text = &模拟登陆百度首页 失败!&;
txbEmulateLoginResult.Text += Environment.NewLine + &所返回的Header信息为:&;
txbEmulateLoginResult.Text += Environment.NewLine + resp.Headers.ToString();
txbEmulateLoginResult.Text += Environment.NewLine + Environment.NewL
txbEmulateLoginResult.Text += Environment.NewLine + &所返回的HTML源码为:&;
txbEmulateLoginResult.Text += Environment.NewLine + loginBaiduRespH
MessageBox.Show(&错误:没有正确获得Cookie BAIDUID 和/或 没有正确提取出token值!&);
如果用户名和密码都是正确的话,即可成功登陆:
当然,如果故意输入错误的用户名和密码,则会显示登陆错误,并且打印出返回的headers值和html代码:
完整的C#模拟登陆百度首页的代码,如下:
using System.Collections.G
using System.D
using System.D
using System.T
using System.Windows.F
using System.N
using System.IO;
using System.Text.RegularE
using System.W
namespace emulateLoginBaidu
public partial class frmEmulateLoginBaidu : Form
CookieCollection curCookies =
bool gotCookieBaiduid, extractTokenValueOK, loginBaiduOk;
public frmEmulateLoginBaidu()
InitializeComponent();
private void frmEmulateLoginBaidu_Load(object sender, EventArgs e)
curCookies = new CookieCollection();
gotCookieBaiduid =
extractTokenValueOK =
loginBaiduOk =
/******************************************************************************
functions in crifanLib.cs
*******************************************************************************/
//quote the input dict values
//note: the return result for first para no '&'
public string quoteParas(Dictionary&string, string& paras)
string quotedParas = &&;
bool isFirst =
string val = &&;
foreach (string para in paras.Keys)
if (paras.TryGetValue(para, out val))
if (isFirst)
quotedParas += para + &=& + HttpUtility.UrlPathEncode(val);
quotedParas += &&& + para + &=& + HttpUtility.UrlPathEncode(val);
return quotedP
/******************************************************************************
Demo emulate login baidu related functions
*******************************************************************************/
private void btnGetBaiduid_Click(object sender, EventArgs e)
string baiduMainUrl = txbBaiduMainUrl.T
//generate http request
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baiduMainUrl);
//add follow code to handle cookies
req.CookieContainer = new CookieContainer();
req.CookieContainer.Add(curCookies);
req.Method = &GET&;
//use request to get response
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
txbGotBaiduid.Text = &&;
foreach (Cookie ck in resp.Cookies)
txbGotBaiduid.Text += &[& + ck.Name + &]=& + ck.V
if (ck.Name == &BAIDUID&)
gotCookieBaiduid =
if (gotCookieBaiduid)
//store cookies
curCookies = resp.C
MessageBox.Show(&错误:没有找到cookie BAIDUID !&);
private void btnGetToken_Click(object sender, EventArgs e)
if (gotCookieBaiduid)
string getapiUrl = &/v2/api/?getapi&class=login&tpl=mn&tangram=true&;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(getapiUrl);
//add previously got cookies
req.CookieContainer = new CookieContainer();
req.CookieContainer.Add(curCookies);
req.Method = &GET&;
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
StreamReader sr = new StreamReader(resp.GetResponseStream());
string respHtml = sr.ReadToEnd();
//bdPass.api.params.login_token='5abe7fbbe1bfc267b90b3';
string tokenValP = @&bdPass\.api\.params\.login_token='(?&tokenVal&\w+)';&;
Match foundTokenVal = (new Regex(tokenValP)).Match(respHtml);
if (foundTokenVal.Success)
//extracted the token value
txbExtractedTokenVal.Text = foundTokenVal.Groups[&tokenVal&].V
extractTokenValueOK =
txbExtractedTokenVal.Text = &错误:没有找到token的值!&;
MessageBox.Show(&错误:之前没有正确获得Cookie:BAIDUID !&);
private void btnEmulateLoginBaidu_Click(object sender, EventArgs e)
if (gotCookieBaiduid && extractTokenValueOK)
string staticpage = &/cache/user/html/jump.html&;
//init post dict info
Dictionary&string, string& postDict = new Dictionary&string, string&();
//postDict.Add(&ppui_logintime&, &&);
postDict.Add(&charset&, &utf-8&);
//postDict.Add(&codestring&, &&);
postDict.Add(&token&, txbExtractedTokenVal.Text);
postDict.Add(&isPhone&, &false&);
postDict.Add(&index&, &0&);
//postDict.Add(&u&, &&);
//postDict.Add(&safeflg&, &0&);
postDict.Add(&staticpage&, staticpage);
postDict.Add(&loginType&, &1&);
postDict.Add(&tpl&, &mn&);
postDict.Add(&callback&, &parent.bdPass.api.login._postCallback&);
postDict.Add(&username&, txbBaiduUsername.Text);
postDict.Add(&password&, txbBaiduPassword.Text);
//postDict.Add(&verifycode&, &&);
postDict.Add(&mem_pass&, &on&);
string baiduMainLoginUrl = &/v2/api/?login&;
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(baiduMainLoginUrl);
//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(postDataStr);
req.ContentLength = postBytes.L
//send post data
Stream postDataStream = req.GetRequestStream();
postDataStream.Write(postBytes, 0, postBytes.Length);
postDataStream.Close();
//got response
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
//got returned html
StreamReader sr = new StreamReader(resp.GetResponseStream());
string loginBaiduRespHtml = sr.ReadToEnd();
//check whether got all expected cookies
Dictionary&string, bool& cookieCheckDict = new Dictionary&string, bool&();
string[] cookiesNameList = {&BDUSS&, &PTOKEN&, &STOKEN&, &SAVEUSERID&};
foreach (String cookieToCheck in cookiesNameList)
cookieCheckDict.Add(cookieToCheck, false);
foreach (Cookie singleCookie in resp.Cookies)
if (cookieCheckDict.ContainsKey(singleCookie.Name))
cookieCheckDict[singleCookie.Name] =
bool allCookiesFound =
foreach (bool foundCurCookie in cookieCheckDict.Values)
allCookiesFound = allCookiesFound && foundCurC
loginBaiduOk = allCookiesF
if (loginBaiduOk)
txbEmulateLoginResult.Text = &成功模拟登陆百度首页!&;
txbEmulateLoginResult.Text = &模拟登陆百度首页 失败!&;
txbEmulateLoginResult.Text += Environment.NewLine + &所返回的Header信息为:&;
txbEmulateLoginResult.Text += Environment.NewLine + resp.Headers.ToString();
txbEmulateLoginResult.Text += Environment.NewLine + Environment.NewL
txbEmulateLoginResult.Text += Environment.NewLine + &所返回的HTML源码为:&;
txbEmulateLoginResult.Text += Environment.NewLine + loginBaiduRespH
MessageBox.Show(&错误:没有正确获得Cookie BAIDUID 和/或 没有正确提取出token值!&);
private void lklEmulateLoginTutorialUrl_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
string emulateLoginTutorialUrl = &/emulate_login_website_using_csharp&;
System.Diagnostics.Process.Start(emulateLoginTutorialUrl);
private void btnClearAll_Click(object sender, EventArgs e)
curCookies = new CookieCollection();
gotCookieBaiduid =
extractTokenValueOK =
loginBaiduOk =
txbGotBaiduid.Text = &&;
txbExtractedTokenVal.Text = &&;
txbBaiduUsername.Text = &&;
txbBaiduPassword.Text = &&;
txbEmulateLoginResult.Text = &&;
对应的,完整的VS2010的C#项目,可以去这里下载:
【版本2:C#实现模拟登陆百度首页的完整代码 之 crifanLib.py版】
后来,又把上述代码,改为利用我的C#版本的crifanLib.cs,以方便以后再次利用相关的网络方面的库函数。
下面是完整的,利用到crifanLib.cs的版本,的C#代码:
using System.Collections.G
using System.D
using System.D
using System.T
using System.Windows.F
using System.N
using System.IO;
using System.Text.RegularE
using System.W
namespace emulateLoginBaidu
public partial class frmEmulateLoginBaidu : Form
CookieCollection curCookies =
bool gotCookieBaiduid, extractTokenValueOK, loginBaiduOk;
public frmEmulateLoginBaidu()
InitializeComponent();
private void frmEmulateLoginBaidu_Load(object sender, EventArgs e)
this.AcceptButton = this.btnEmulateLoginB
//init for crifanLib.cs
curCookies = new CookieCollection();
//init for demo login
gotCookieBaiduid =
extractTokenValueOK =
loginBaiduOk =
/******************************************************************************
functions in crifanLib.cs
Online browser: /p/crifanlib/source/browse/trunk/csharp/crifanLib.cs
/p/crifanlib/
*******************************************************************************/
//quote the input dict values
//note: the return result for first para no '&'
public string quoteParas(Dictionary&string, string& paras)
string quotedParas = &&;
bool isFirst =
string val = &&;
foreach (string para in paras.Keys)
if (paras.TryGetValue(para, out val))
if (isFirst)
quotedParas += para + &=& + HttpUtility.UrlPathEncode(val);
quotedParas += &&& + para + &=& + HttpUtility.UrlPathEncode(val);
return quotedP
/*********************************************************************/
/* cookie */
/*********************************************************************/
//add a single cookie to cookies, if already exist, update its value
public void addCookieToCookies(Cookie toAdd, ref CookieCollection cookies, bool overwriteDomain)
bool found =
if (cookies.Count & 0)
foreach (Cookie originalCookie in cookies)
if (originalCookie.Name == toAdd.Name)
// !!! for different domain, cookie is not same,
// so should not set the cookie value here while their domains is not same
// only if it explictly need overwrite domain
if ((originalCookie.Domain == toAdd.Domain) ||
((originalCookie.Domain != toAdd.Domain) && overwriteDomain))
//here can not force convert CookieCollection to HttpCookieCollection,
//then use .remove to remove this cookie then add
// so no good way to copy all field value
originalCookie.Value = toAdd.V
originalCookie.Domain = toAdd.D
originalCookie.Expires = toAdd.E
originalCookie.Version = toAdd.V
originalCookie.Path = toAdd.P
//following fields seems should not change
//originalCookie.HttpOnly = toAdd.HttpO
//originalCookie.Secure = toAdd.S
if (!found)
if (toAdd.Domain != &&)
// if add the null domain, will lead to follow req.CookieContainer.Add(cookies) failed !!!
cookies.Add(toAdd);
}//addCookieToCookies
//add singel cookie to cookies, default no overwrite domain
public void addCookieToCookies(Cookie toAdd, ref CookieCollection cookies)
addCookieToCookies(toAdd, ref cookies, false);
//check whether the cookies contains the ckToCheck cookie
//support:
//ckTocheck is Cookie/string
//cookies is Cookie/string/CookieCollection/string[]
public bool isContainCookie(object ckToCheck, object cookies)
bool isContain =
if ((ckToCheck != null) && (cookies != null))
string ckName = &&;
Type type = ckToCheck.GetType();
//string typeStr = ckType.ToString();
//if (ckType.FullName == &System.string&)
if (type.Name.ToLower() == &string&)
ckName = (string)ckToC
else if (type.Name == &Cookie&)
ckName = ((Cookie)ckToCheck).N
if (ckName != &&)
type = cookies.GetType();
// is single Cookie
if (type.Name == &Cookie&)
if (ckName == ((Cookie)cookies).Name)
isContain =
// is CookieCollection
else if (type.Name == &CookieCollection&)
foreach (Cookie ck in (CookieCollection)cookies)
if (ckName == ck.Name)
isContain =
// is single cookie name string
else if (type.Name.ToLower() == &string&)
if (ckName == (string)cookies)
isContain =
// is cookie name string[]
else if (type.Name.ToLower() == &string[]&)
foreach (string name in ((string[])cookies))
if (ckName == name)
isContain =
return isC
}//isContainCookie
// update cookiesToUpdate to localCookies
// if omitUpdateCookies designated, then omit cookies of omitUpdateCookies in cookiesToUpdate
public void updateLocalCookies(CookieCollection cookiesToUpdate, ref CookieCollection localCookies, object omitUpdateCookies)
if (cookiesToUpdate.Count & 0)
if (localCookies == null)
localCookies = cookiesToU
foreach (Cookie newCookie in cookiesToUpdate)
if (isContainCookie(newCookie, omitUpdateCookies))
// need omit process this
addCookieToCookies(newCookie, ref localCookies);
}//updateLocalCookies
//update cookiesToUpdate to localCookies
public void updateLocalCookies(CookieCollection cookiesToUpdate, ref CookieCollection localCookies)
updateLocalCookies(cookiesToUpdate, ref localCookies, null);
/*********************************************************************/
/* HTTP */
/*********************************************************************/
/* get url's response */
public HttpWebResponse getUrlResponse(string url,
Dictionary&string, string& headerDict,
Dictionary&string, string& postDict,
int timeout,
string postDataStr)
//CookieCollection parsedC
HttpWebResponse resp =
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.AllowAutoRedirect =
req.Accept = &*/*&;
//const string gAcceptLanguage = &en-US&; // zh-CN/en-US
//req.Headers[&Accept-Language&] = gAcceptL
req.KeepAlive =
//const string gUserAgent = &Mozilla/4.0 ( MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E&;
//const string gUserAgent = &Mozilla/5.0 ( MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)&; // x64
const string gUserAgent = &Mozilla/5.0 ( MSIE 9.0; Windows NT 6.1; Trident/5.0)&; // x86
//const string gUserAgent = &Mozilla/5.0 (W U; Windows NT 6.1; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.99 Safari/533.4&;
//Mozilla Firefox
//const string gUserAgent = &Mozilla/5.0 (W U; Windows NT 6.1; rv:1.9.2.6) Gecko/ Firefox/3.6.6&;
req.UserAgent = gUserA
req.Headers[&Accept-Encoding&] = &gzip, deflate&;
req.AutomaticDecompression = DecompressionMethods.GZ
req.Proxy =
if (timeout & 0)
req.Timeout =
if (curCookies != null)
req.CookieContainer = new CookieContainer();
req.CookieContainer.PerDomainCapacity = 40; // following will exceed max default 20 cookie per domain
req.CookieContainer.Add(curCookies);
if (headerDict != null)
foreach (string header in headerDict.Keys)
string headerValue = &&;
if (headerDict.TryGetValue(header, out headerValue))
// following are allow the caller overwrite the default header setting
if (header.ToLower() == &referer&)
req.Referer = headerV
else if (header.ToLower() == &allowautoredirect&)
bool isAllow =
if (bool.TryParse(headerValue, out isAllow))
req.AllowAutoRedirect = isA
else if (header.ToLower() == &accept&)
req.Accept = headerV
else if (header.ToLower() == &keepalive&)
bool isKeepAlive =
if (bool.TryParse(headerValue, out isKeepAlive))
req.KeepAlive = isKeepA
else if (header.ToLower() == &accept-language&)
req.Headers[&Accept-Language&] = headerV
else if (header.ToLower() == &useragent&)
req.UserAgent = headerV
req.Headers[header] = headerV
if (postDict != null || postDataStr != &&)
req.Method = &POST&;
req.ContentType = &application/x-www-form-urlencoded&;
if (postDict != null)
postDataStr = quoteParas(postDict);
//byte[] postBytes = Encoding.GetEncoding(&utf-8&).GetBytes(postData);
byte[] postBytes = Encoding.UTF8.GetBytes(postDataStr);
req.ContentLength = postBytes.L
Stream postDataStream = req.GetRequestStream();
postDataStream.Write(postBytes, 0, postBytes.Length);
postDataStream.Close();
req.Method = &GET&;
//may timeout, has fixed in:
///fixed_problem_sometime_httpwebrequest_getresponse_timeout/
resp = (HttpWebResponse)req.GetResponse();
updateLocalCookies(resp.Cookies, ref curCookies);
public HttpWebResponse getUrlResponse(string url,
Dictionary&string, string& headerDict,
Dictionary&string, string& postDict)
return getUrlResponse(url, headerDict, postDict, 0, &&);
public HttpWebResponse getUrlResponse(string url)
return getUrlResponse(url, null, null, 0, &&);
// valid charset:&GB18030&/&UTF-8&, invliad:&UTF8&
public string getUrlRespHtml(string url,
Dictionary&string, string& headerDict,
string charset,
Dictionary&string, string& postDict,
int timeout,
string postDataStr)
string respHtml = &&;
//HttpWebResponse resp = getUrlResponse(url, headerDict, postDict, timeout);
HttpWebResponse resp = getUrlResponse(url, headerDict, postDict, timeout, postDataStr);
//long realRespLen = resp.ContentL
if ((charset != null) && (charset != &&))
Encoding htmlEncoding = Encoding.GetEncoding(charset);
sr = new StreamReader(resp.GetResponseStream(), htmlEncoding);
sr = new StreamReader(resp.GetResponseStream());
respHtml = sr.ReadToEnd();
return respH
public string getUrlRespHtml(string url, Dictionary&string, string& headerDict, string charset, Dictionary&string, string& postDict, string postDataStr)
return getUrlRespHtml(url, headerDict, charset, postDict, 0, postDataStr);
public string getUrlRespHtml(string url, Dictionary&string, string& headerDict, Dictionary&string, string& postDict)
return getUrlRespHtml(url, headerDict, &&, postDict, &&);
public string getUrlRespHtml(string url, Dictionary&string, string& headerDict)
return getUrlRespHtml(url, headerDict, null);
public string getUrlRespHtml(string url, string charset, int timeout)
return getUrlRespHtml(url, null, charset, null, timeout, &&);
public string getUrlRespHtml(string url, string charset)
return getUrlRespHtml(url, charset, 0);
public string getUrlRespHtml(string url)
return getUrlRespHtml(url, &&);
/******************************************************************************
Demo emulate login baidu related functions
*******************************************************************************/
private void btnGetBaiduid_Click(object sender, EventArgs e)
string baiduMainUrl = txbBaiduMainUrl.T
HttpWebResponse resp = getUrlResponse(baiduMainUrl);
txbGotBaiduid.Text = &&;
foreach (Cookie ck in resp.Cookies)
txbGotBaiduid.Text += &[& + ck.Name + &]=& + ck.V
if (ck.Name == &BAIDUID&)
gotCookieBaiduid =
if (gotCookieBaiduid)
//store cookies
curCookies = resp.C
MessageBox.Show(&错误:没有找到cookie BAIDUID !&);
private void btnGetToken_Click(object sender, EventArgs e)
if (gotCookieBaiduid)
string getapiUrl = &/v2/api/?getapi&class=login&tpl=mn&tangram=true&;
string respHtml = getUrlRespHtml(getapiUrl);
//bdPass.api.params.login_token='5abe7fbbe1bfc267b90b3';
string tokenValP = @&bdPass\.api\.params\.login_token='(?&tokenVal&\w+)';&;
Match foundTokenVal = (new Regex(tokenValP)).Match(respHtml);
if (foundTokenVal.Success)
//extracted the token value
txbExtractedTokenVal.Text = foundTokenVal.Groups[&tokenVal&].V
extractTokenValueOK =
txbExtractedTokenVal.Text = &错误:没有找到token的值!&;
MessageBox.Show(&错误:之前没有正确获得Cookie:BAIDUID !&);
private void btnEmulateLoginBaidu_Click(object sender, EventArgs e)
if (gotCookieBaiduid && extractTokenValueOK)
string staticpage = &/cache/user/html/jump.html&;
//init post dict info
Dictionary&string, string& postDict = new Dictionary&string, string&();
//postDict.Add(&ppui_logintime&, &&);
postDict.Add(&charset&, &utf-8&);
//postDict.Add(&codestring&, &&);
postDict.Add(&token&, txbExtractedTokenVal.Text);
postDict.Add(&isPhone&, &false&);
postDict.Add(&index&, &0&);
//postDict.Add(&u&, &&);
//postDict.Add(&safeflg&, &0&);
postDict.Add(&staticpage&, staticpage);
postDict.Add(&loginType&, &1&);
postDict.Add(&tpl&, &mn&);
postDict.Add(&callback&, &parent.bdPass.api.login._postCallback&);
postDict.Add(&username&, txbBaiduUsername.Text);
postDict.Add(&password&, txbBaiduPassword.Text);
//postDict.Add(&verifycode&, &&);
postDict.Add(&mem_pass&, &on&);
string baiduMainLoginUrl = &/v2/api/?login&;
string loginBaiduRespHtml = getUrlRespHtml(baiduMainLoginUrl, null, postDict);
//check whether got all expected cookies
Dictionary&string, bool& cookieCheckDict = new Dictionary&string, bool&();
string[] cookiesNameList = {&BDUSS&, &PTOKEN&, &STOKEN&, &SAVEUSERID&};
foreach (String cookieToCheck in cookiesNameList)
cookieCheckDict.Add(cookieToCheck, false);
foreach (Cookie singleCookie in curCookies)
if (cookieCheckDict.ContainsKey(singleCookie.Name))
cookieCheckDict[singleCookie.Name] =
bool allCookiesFound =
foreach (bool foundCurCookie in cookieCheckDict.Values)
allCookiesFound = allCookiesFound && foundCurC
loginBaiduOk = allCookiesF
if (loginBaiduOk)
txbEmulateLoginResult.Text = &成功模拟登陆百度首页!&;
txbEmulateLoginResult.Text = &模拟登陆百度首页 失败!&;
txbEmulateLoginResult.Text += Environment.NewLine + &所返回的HTML源码为:&;
txbEmulateLoginResult.Text += Environment.NewLine + loginBaiduRespH
MessageBox.Show(&错误:没有正确获得Cookie BAIDUID 和/或 没有正确提取出token值!&);
private void lklEmulateLoginTutorialUrl_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
string emulateLoginTutorialUrl = &/emulate_login_website_using_csharp&;
System.Diagnostics.Process.Start(emulateLoginTutorialUrl);
private void btnClearAll_Click(object sender, EventArgs e)
curCookies = new CookieCollection();
gotCookieBaiduid =
extractTokenValueOK =
loginBaiduOk =
txbGotBaiduid.Text = &&;
txbExtractedTokenVal.Text = &&;
txbBaiduUsername.Text = &&;
txbBaiduPassword.Text = &&;
txbEmulateLoginResult.Text = &&;
完整的VS2010的项目,可去这里下载:
关于crifanLib.cs:
在线浏览:
可以看出,虽然之前分析出来的,模拟登陆百度首页的流程,相对不是那么复杂,但是实际上用C#实现起来,要比,要复杂的多。
主要原因在于,Python中封装了很多常用的,好用的库函数。而C#中,很多细节,都需要自己处理,包括GET或POST时的各种参数,都要考虑到,另外尤其是涉及cookie等方面的内容,很是繁琐。
所以,对于抓取网页分析内容,和模拟登陆网站来说,还是Python用起来比较方便。
1.经过研究:
之前的代码, 在.NET 3.5之前,都是正常工作的,而在.NET 4.0中,是不工作的;
2.现已找到原因并修复。
.NET 4.0,对于没有指定expires域的cookie,会把cookie的expires域值设置成默认的秒,由此导致该cookie过期失效,导致百度的那个cookie:
H_PS_PSSID
失效,导致后续操作都异常了。
而.NET 3.5之前,虽然cookie的expires域值也是默认的秒,但是实际上cookie还是可用的,所以后续就正常,就不会发生此问题;
3.修复后的代码:
(1)模拟百度登陆 独立完整代码版本 .NET 4.0
(2)模拟百度登陆 (利用我自己的)crifanLib版本 .NET 4.0
(抽空再上传上面两个文件,因为此处上传出错:
unknown Bytes complete FAILED!
:Upload canceled
: VIRUS DETECTED!
(Heuristics.Broken.Executable FOUND)
抽空换个时间上传试试。还是同样错误的话,再去解决。)
.NET 不论是3.5以及之前,还是最新的4.0,在解析http的response中的Set-Cookie变成CookieCollection方面:
一直就是狗屎,bug一堆。
以后,能少用那个resp.Cookies,就少用吧。
否则被C#玩死,都不知道怎么死的。
还是用自己写的那个解析函数去解析Set-Cookie,得到正确的CookieCollection吧。
共享此文章:
免费的格式化Javascript源码的网站
查询Unicode字符,且还带Oct,Decimal,Hex,HTML Entity
HTML和Javascript都支持,很好用。}

我要回帖

更多关于 cookie world咖啡 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信