C# 使用分页刮取ASP.NET网站

C# 使用分页刮取ASP.NET网站,c#,asp.net,httpwebrequest,C#,Asp.net,Httpwebrequest,我试图刮一个基本的asp.net目录网站,其中有分页 该网站有50多个页面,每个页面上最多包含10个页面链接 我使用fiddler来帮助复制使用浏览器发布的所有参数、变量、表单字段、cookie等。我在两篇文章中看到的唯一区别是\uu EVENTVALIDATION值 使用HttpWebRequest时,我始终具有相同的值,同时通过浏览器在每次单击时进行更改 使用HttpWebRequest,我正确地获得了前10页,但是接下来的所有页面都将我重定向到主页。Bellow是post-back jav

我试图刮一个基本的asp.net目录网站,其中有分页

该网站有50多个页面,每个页面上最多包含10个页面链接

我使用fiddler来帮助复制使用浏览器发布的所有参数、变量、表单字段、cookie等。我在两篇文章中看到的唯一区别是
\uu EVENTVALIDATION

使用HttpWebRequest时,我始终具有相同的值,同时通过浏览器在每次单击时进行更改

使用HttpWebRequest,我正确地获得了前10页,但是接下来的所有页面都将我重定向到主页。Bellow是post-back javascript,前10个链接之后的链接总是相同的

javascript:__doPostBack('CT_Main_2$gvDirectorySearch$ctl53$ctl00$ctl11','')

你知道为什么
\u EVENTVALIDATION
不会随HttpWebRequest而改变吗?

根据你的描述,它听起来像一个
防伪令牌
,一个
防伪令牌
用于防止
跨站点请求伪造(XSRF)
攻击

对于要利用防伪令牌的站点,它通常会在客户端浏览器中设置一个cookie,并且它会期望与正在发布的表单中的参数相同的令牌

为了克服这个问题,您需要发送服务器在后续请求中设置的令牌,您还需要扫描HTML表单中的相同令牌,并将其包括在内


编辑 所以我深入挖掘了一下,创建了一个ASP.NETWebForms网站,并试图复制您的问题,但无法。。。每次请求时,我都设法提取
\uu EVENTVALIDATION
字段

不过,如果你觉得有什么有用的话,这是我的代码

void Main()
{
    string eventValidationToken = string.Empty;
    
    var firstResponse = this.Get(@"http://localhost:7428/Account/Login");
    
    firstResponse.FormValues["ctl00$MainContent$Email"] = "email@example.com";
    firstResponse.FormValues["ctl00$MainContent$Password"] = "password";

    string secondRequestPostdata = firstResponse.ToString();
    var secondResponse = this.Post(@"http://localhost:7428/Account/Login", secondRequestPostdata);
    
    Console.WriteLine (firstResponse.FormValues["__EVENTVALIDATION"]);
    Console.WriteLine (secondResponse.FormValues["__EVENTVALIDATION"]);
}


public FormData Get(string uri)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://localhost:7428/Account/Login");
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    using (Stream stream = response.GetResponseStream())
    using (StreamReader reader = new StreamReader(stream))
    {
        return  new FormData(reader.ReadToEnd());
    }
}

public FormData Post(string uri, string postContent)
{
    byte[] formBytes = Encoding.UTF8.GetBytes(postContent);
    
    var request = (HttpWebRequest)WebRequest.Create("http://localhost:7428/Account/Login");
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = formBytes.Length;
    
    using (Stream stream = request.GetRequestStream())
    {
        stream.Write(formBytes, 0, formBytes.Length);
    }
    
    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    using (Stream stream = response.GetResponseStream())
    using (StreamReader reader = new StreamReader(stream))
    {
        return new FormData(reader.ReadToEnd());
    }
}

public class FormData
{
    public FormData(string html)
    {
        this.Html = html;
    
        this.FormValues = new Dictionary<string, string>();
        this.FormValues["__EVENTTARGET"]                = this.Extract(@"__EVENTTARGET");
        this.FormValues["__EVENTARGUMENT"]              = this.Extract(@"__EVENTARGUMENT");
        this.FormValues["__VIEWSTATE"]                  = this.Extract(@"__VIEWSTATE");
        this.FormValues["__VIEWSTATEGENERATOR"]         = this.Extract(@"__VIEWSTATEGENERATOR");
        this.FormValues["__EVENTVALIDATION"]            = this.Extract(@"__EVENTVALIDATION");
        this.FormValues["ctl00$MainContent$Email"]      = string.Empty;
        this.FormValues["ctl00$MainContent$Password"]   = string.Empty;
        this.FormValues["ctl00$MainContent$ctl05"]      = "Log in";
    }
    
    public string Html { get; set; }
    
    private string Extract(string id)
    {
        return Regex.Match(this.Html, @"id=""" + id + @""" value=""([^""]*)")
                    .Groups[1]
                    .Value;
    }
    
    public Dictionary<string, string> FormValues { get;set; }
    
    public override string ToString()
    {
        var formData = this.FormValues.Select(form => HttpUtility.UrlEncode(form.Key) + "=" + HttpUtility.UrlEncode(form.Value));
                        
        return string.Join("&", formData);
    }
}
void Main()
{
string eventValidationToken=string.Empty;
var firstResponse=this.Get(@)http://localhost:7428/Account/Login");
firstResponse.FormValues[“ctl00$MainContent$Email”]=”email@example.com";
firstResponse.FormValues[“ctl00$MainContent$Password”]=“Password”;
字符串secondRequestPostdata=firstResponse.ToString();
var secondResponse=this.Post(@)http://localhost:7428/Account/Login“,secondRequestPostdata);
Console.WriteLine(firstResponse.FormValues[“\uu EVENTVALIDATION]”);
Console.WriteLine(secondResponse.FormValues[“\uu EVENTVALIDATION”]);
}
public FormData Get(字符串uri)
{
HttpWebRequest请求=(HttpWebRequest)WebRequest.Create(“http://localhost:7428/Account/Login");
使用(HttpWebResponse=(HttpWebResponse)request.GetResponse())
使用(Stream=response.GetResponseStream())
使用(StreamReader=新StreamReader(stream))
{
返回新的FormData(reader.ReadToEnd());
}
}
public FormData Post(字符串uri、字符串postContent)
{
byte[]formBytes=Encoding.UTF8.GetBytes(postContent);
var request=(HttpWebRequest)WebRequest.Create(“http://localhost:7428/Account/Login");
request.Method=“POST”;
request.ContentType=“application/x-www-form-urlencoded”;
request.ContentLength=formBytes.Length;
使用(Stream=request.GetRequestStream())
{
stream.Write(formBytes,0,formBytes.Length);
}
使用(HttpWebResponse=(HttpWebResponse)request.GetResponse())
使用(Stream=response.GetResponseStream())
使用(StreamReader=新StreamReader(stream))
{
返回新的FormData(reader.ReadToEnd());
}
}
公共类FormData
{
公共表单数据(字符串html)
{
this.Html=Html;
this.FormValues=新字典();
this.FormValues[“\uu EVENTTARGET”]=this.Extract(@“\uu EVENTTARGET”);
this.FormValues[“\uu EVENTARGUMENT”]=this.Extract(@“\uu EVENTARGUMENT”);
this.FormValues[“_VIEWSTATE”]=this.Extract(@“_VIEWSTATE”);
this.FormValues[“\uu VIEWSTATEGENERATOR”]=this.Extract(@“\uu VIEWSTATEGENERATOR”);
this.FormValues[“\uu EVENTVALIDATION”]=this.Extract(@“\uu EVENTVALIDATION”);
this.FormValues[“ctl00$MainContent$Email”]=string.Empty;
this.FormValues[“ctl00$MainContent$Password”]=string.Empty;
this.FormValues[“ctl00$MainContent$ctl05”]=“登录”;
}
公共字符串Html{get;set;}
私有字符串提取(字符串id)
{
返回Regex.Match(this.Html,@“id=”“”+id+@“value=”“([^”“]*)”)
.小组[1]
价值
}
公共字典FormValues{get;set;}
公共重写字符串ToString()
{
var formData=this.FormValues.Select(form=>HttpUtility.UrlEncode(form.Key)+“=”+HttpUtility.UrlEncode(form.Value));
返回string.Join(“&”,formData);
}
}

可能重复不幸的是,这不是同一个问题。如果您注意到在我的情况下,我没有:uu doPostBack('gvEmployees','Page$2')“>2页面$2参数。我相信页面之间的差异是通过EventvValidation fieldhmm确定的,我在fiddler中没有看到任何类似于防伪令牌的额外参数,而且我已经在帖子中获得并传递了所有cookies。我只是不明白为什么我的Eventvalidation值没有改变。所以当您启动第一个
HttpWebRequest
。。。观察fiddler时,服务器是否没有在响应时设置名为
\uu EVENTVALIDATION
的令牌?在第一步中,我获取原始cookie和令牌,这些cookie和令牌也设置了正确的事件验证。尽管我的EVENTVALIDATION在所有帖子中都具有相同的值,但我使用这些信息发布并获得正确的结果(如上所述)。当我点击第11页(不在原始网页中)时,问题就开始了。在那之后,我总是被重定向到主页。是的,这就是问题所在,一旦你发送
HttpWebRequest
,你就不是在读正文寻找一个新的令牌了,你没有