给梦一个奔跑的方向!
PDF Print E-mail
User Rating: / 0
PoorBest 
Written by xlingfairy
Saturday, 31 October 2009 14:15
要抓取某个网站的数据,但是该网站不提供列表,只提供了一个按分类查询的功能。
每次查询要先提供近40K(相当的大了,主要是因为 __VIEWSTATE 这个参数,.NET网站都有这个东东)的数据到网站,然后在 302 跳转到某个页面上。

昨天我耗了N长时间在这个上面,我把所有该发送的数据都发送了,但是一直没有发生 302 跳转。
跟踪了很长时间,我发现在 302 跳转之前的那个 Response 发送回来一个名为 ASP.NET_SessionId 的 cookie ,我认为是在请求的时候,没有把这个 cookie 给发送出去的原因,于是就想着怎么在请求的时候,不自动 redirect ,这样就可以在 response 的时取回这个 cookie 了(事实上跟本就没有发生重定向),接着在请求要重定向的地址。。。于是:

req.AllowAutoRedirect = false;

但是结果还是一样, response.StatusCode = OK, 跟本就不是  302

后来我又想,得不到这个 sessionID,我就手动给它加个吧:

Cookie cookSession = new Cookie("ASP.NET_SessionId" , "2fohl0qqvaxkyc450cmpqa2k");//这个值是从抓包软件里取得的。
cookSession.Domain = "www.nzsport.co.nz/";
cookSession.HttpOnly = true;
cookSession.Path = "/";

cookies.Add(cookSession);
req.CookieContainer = new CookieContainer();
req.CookieContainer.Add(cookies);

运行后,结果还是一样。。。


在后来,认真看了看抓包结果,发现 request 的 Content-Type 是
multipart/form-data; boundary=---------------------------491299511942

POST 的数据原始格式是:

-----------------------------491299511942
Content-Disposition: form-data; name="__EVENTTARGET"


-----------------------------491299511942
Content-Disposition: form-data; name="__EVENTARGUMENT"

。。。
。。。
-----------------------------491299511942--

于是按照着这个格式重新组织数据:

Dictionary<string , string> postDatas = new Dictionary<string , string>();
postDatas.Add("__dnnVariable" , dnnVariable);
postDatas.Add("__EVENTARGUMENT" , "");
postDatas.Add("__EVENTTARGET" , "");
postDatas.Add("__LASTFOCUS" , "");
postDatas.Add("__VIEWSTATE" , viewState);
。。。
。。。
string postData = "";

foreach( string item in postDatas.Keys ) {
    postData += string.Format("-----------------------------491299511942\r\nContent-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}\r\n",item, postDatas[item]);
    //postData += string.Format("{0}={1}&",item, System.Web.HttpUtility.UrlEncode( postDatas[item] ));
}

postData += "-----------------------------491299511942--";

req.ContentType = "multipart/form-data; boundary=-----------------------------491299511942";

运行之后,仍然没有成功,在认真比较一下,发现
multipart/form-data; boundary=---------------------------491299511942 中 boundary= 后面的部分 其实是比 上面 foreach 段里的那个 要少两个中线( - ),改过来就可以了。(少两个中线才是正确的,不要误解。。。)

至于一开始用 req.ContentType = "application/x-www-form-urlencoded"; 没有成功,是因为没有对 post 的数据进行 UrlEncode ,加上 UrlEncode 就行了。

postData += string.Format("{0}={1}&",item, System.Web.HttpUtility.UrlEncode( postDatas[item] ));
Last Updated ( Saturday, 31 October 2009 14:24 )
 

Add comment


Security code
Refresh

Popular Contents

Recommend

Site Info

Members : 1
Content : 130
Web Links : 7
Content View Hits : 99657

Links