当前位置:编程学习 > C#/ASP.NET >>

post之前如何获得viewstate

用apache模拟登录抓取网页数据时,有post请求
请问怎么在post之前获取viewstate呢?
请大神们指点一下viewstate的生成原理,怎么才能看出一个网页怎么生成的viewstate呢? viewstate --------------------编程问答--------------------
引用 楼主 Faint06 的回复:
用apache模拟登录抓取网页数据时,有post请求
请问怎么在post之前获取viewstate呢?
请大神们指点一下viewstate的生成原理,怎么才能看出一个网页怎么生成的viewstate呢?
private string ExtractViewState(string s)
{
   string viewStateNameDelimiter = "__VIEWSTATE";
   string valueDelimiter = "value=\"";
            
   int viewStateNamePosition = s.IndexOf(viewStateNameDelimiter);     
   int viewStateValuePosition = s.IndexOf(
         valueDelimiter, viewStateNamePosition
      );

   int viewStateStartPosition = viewStateValuePosition + 
                                valueDelimiter.Length;
   int viewStateEndPosition = s.IndexOf("\"", viewStateStartPosition);

   return HttpUtility.UrlEncodeUnicode(
            s.Substring(
               viewStateStartPosition, 
               viewStateEndPosition - viewStateStartPosition
            )
         );  
}
--------------------编程问答--------------------
引用 1 楼 rayaspnet 的回复:
Quote: 引用 楼主 Faint06 的回复:

用apache模拟登录抓取网页数据时,有post请求
请问怎么在post之前获取viewstate呢?
请大神们指点一下viewstate的生成原理,怎么才能看出一个网页怎么生成的viewstate呢?
private string ExtractViewState(string s)
{
   string viewStateNameDelimiter = "__VIEWSTATE";
   string valueDelimiter = "value=\"";
            
   int viewStateNamePosition = s.IndexOf(viewStateNameDelimiter);     
   int viewStateValuePosition = s.IndexOf(
         valueDelimiter, viewStateNamePosition
      );

   int viewStateStartPosition = viewStateValuePosition + 
                                valueDelimiter.Length;
   int viewStateEndPosition = s.IndexOf("\"", viewStateStartPosition);

   return HttpUtility.UrlEncodeUnicode(
            s.Substring(
               viewStateStartPosition, 
               viewStateEndPosition - viewStateStartPosition
            )
         );  
}

好吧,我错了。其实我是做Java的,要抓一个.NET网站。我只是来问问viewstate的原理,结果没说清楚,害的你白写了一段代码- - --------------------编程问答--------------------
引用 2 楼 Faint06 的回复:
Quote: 引用 1 楼 rayaspnet 的回复:

Quote: 引用 楼主 Faint06 的回复:

用apache模拟登录抓取网页数据时,有post请求
请问怎么在post之前获取viewstate呢?
请大神们指点一下viewstate的生成原理,怎么才能看出一个网页怎么生成的viewstate呢?
private string ExtractViewState(string s)
{
   string viewStateNameDelimiter = "__VIEWSTATE";
   string valueDelimiter = "value=\"";
            
   int viewStateNamePosition = s.IndexOf(viewStateNameDelimiter);     
   int viewStateValuePosition = s.IndexOf(
         valueDelimiter, viewStateNamePosition
      );

   int viewStateStartPosition = viewStateValuePosition + 
                                valueDelimiter.Length;
   int viewStateEndPosition = s.IndexOf("\"", viewStateStartPosition);

   return HttpUtility.UrlEncodeUnicode(
            s.Substring(
               viewStateStartPosition, 
               viewStateEndPosition - viewStateStartPosition
            )
         );  
}

好吧,我错了。其实我是做Java的,要抓一个.NET网站。我只是来问问viewstate的原理,结果没说清楚,害的你白写了一段代码- -

明白了? --------------------编程问答--------------------
引用 3 楼 rayaspnet 的回复:
明白了?


不是啊,我是要用Java写代码,你写了个C#代码对我- - --------------------编程问答-------------------- 你直接用FF来查看__VIEWSTATE保存的是什么,照搬过去提交不就好了吗 --------------------编程问答--------------------
引用 5 楼 liuchaolin 的回复:
你直接用FF来查看__VIEWSTATE保存的是什么,照搬过去提交不就好了吗

这个网站的viewstate是根据数据的变化而变化的 --------------------编程问答-------------------- 获取viewstate的两个方法,第一个方法执行会调用第二个

private String[] fetchViewStateByUrl(String url) throws MessageException
{
BasicHttpGetProcessor httpGet = null;
String content = "";
try
{
httpGet = new BasicHttpGetProcessor(getHttpclient() , url);
HttpResponse response = httpGet.sendGet();
content = EntityUtils.toString(response.getEntity());
}
catch(Exception e)
{
if(httpGet != null)
{
httpGet.cancel();
}
e.printStackTrace();
throw new MessageException("抓取出现异常");
}
finally
{
if(httpGet != null)
{
httpGet.close();
}
}

return fetchViewStateByHtml(content);
}

private String[] fetchViewStateByHtml(String html) throws MessageException
{
String[] result = new String[2];
try
{
Parser parser = Parser.createParser(html , "UTF-8");
NodeFilter filter = new NodeClassFilter(InputTag.class);
NodeList nodeList =parser.extractAllNodesThatMatch(filter);
InputTag inputTag1 = null;
InputTag inputTag2 = null;
for(int i = 0 ; i < nodeList.size() ; i++)
{
InputTag it = (InputTag)nodeList.elementAt(i);
String name = it.getAttribute("name");
if("__VIEWSTATE".equals(name))
{
inputTag1 = it;
}
if("__EVENTVALIDATION".equals(name))
{
inputTag2 = it;
}
}

if(inputTag1 != null)
{
result[0] = inputTag1.getAttribute("value");
}
if(inputTag2 != null)
{
result[1] = inputTag2.getAttribute("value");
}
}
catch(Exception e)
{
e.printStackTrace();
throw new MessageException("抓取出现异常!");
}

return result;
}

一般页面的viewstate,是post的url传入第一个方法,然后get请求url得到的content,最后parser出来的
有一些页面的viewstate与get得到的viewstate不同,应该直接用第二个方法parser前一个页面运行之后的content,就能得到变化的viewstate。
我的问题就是这样解决的,不知道还有其它情况没 --------------------编程问答-------------------- 要把 ViewState 通过数据库或其他持久化设备来维持,则需要采用特定的 LosFormatter 类来序列化,反序列化。(serialize, deserialize)
 ViewState Saved in Custom Store:
protected override object LoadPageStateFromPersistenceMedium() 
{
LosFormatter format = new LosFormatter();
return format.Deserialize(YourDataStore["ViewState"]);
}
protected override void SavePageStateToPersistenceMedium(object viewState) 
{
LosFormatter format = new LosFormatter();
StringWriter writer = new StringWriter();
format.Serialize(writer, viewState);
YourDataStore["ViewState"] = writer.ToString();
}

看一下 ViewState 的内部格式到底是什么。
每个控件的 ViewState 保存在一个三元组中(Triplet, System.Web.UI.Triplet).
其 First 对象是:
一个 Pair(System.Web.UI.Pair)

Array or Pairs, of ArrayLists of related name-values.
Second 对象:
该控件在控件树中的索引的 ArrayList
Third 对象:
子控件的类似的三元组的 ArrayList
补充:.NET技术 ,  ASP.NET
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,