2015-04-19 67 views
2

我想抓一个基本的asp.net目录网站,它有分页。用分页刮去ASP.NET网站

该网站有超过50个页面,每页最多可包含10个分页链接。

我使用fiddler来帮助复制使用浏览器发布的所有参数,变量,表单域,cookie等。我在两个帖子之间看到的唯一区别是__EVENTVALIDATION值。

使用HttpWebRequest我总是有相同的价值,而通过浏览器更改每次点击。

使用HttpWebRequest我正确地获得了10个第一页,但接下来的所有页面都将我重定向到主页。贝娄发布的JavaScript后面的第一个10后的链接总是相同的。

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

任何想法为什么__EVENTVALIDATION不会改变HttpWebRequest?

+0

可能重复http://stackoverflow.com/questions/2449328/how-do-i-scrape-in​​formation-off -asp-net-websites-when-paging-and-javascript-links –

+0

不幸的是,它不是同一个问题。如果你注意到我的情况,我没有:__ doPostBack('gvEmployees','Page $ 2')“> 2页面2的参数。我相信页面之间的差异是通过EventVValidation字段 – Jim

回答

2

从你的描述,这听起来像一个anti-forgery token,一个anti-forgery token用于防止cross-site request forgery (XSRF)攻击..

对于网站采取的防伪标记的优势,它通常会设置在客户端的浏览器中的cookie ,并且它将期望与正在发布的表单中的参数非常相似。

为了克服它,您需要发送服务器在后续请求中设置的令牌,您还需要扫描HTML表单以获得相同的标记并将其包含在内。


编辑

所以我挖得更深一些,并创建了一个ASP.NET WebForms的网站,并试图复制你的问题,但不能......对每个请求我设法提取__EVENTVALIDATION领域。

不过,这里是我的代码,如果你发现任何有用...

void Main() 
{ 
    string eventValidationToken = string.Empty; 

    var firstResponse = this.Get(@"http://localhost:7428/Account/Login"); 

    firstResponse.FormValues["ctl00$MainContent$Email"] = "[email protected]"; 
    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); 
    } 
} 
+0

确定的。看到在提琴手任何额外的参数,类似于防伪造的令牌,也是我已经得到并通过所有的cookies与帖子。我只是不明白为什么我的Eventvalidation值不会改变。 – Jim

+0

因此,当你开火你的第一个'HttpWebRequest' ...当观察fiddler是服务器没有设置一个名为'__EVENTVALIDATION'的响应吗? –

+0

第一步我做一个GET并抓取原始的cookie和令牌,它们也设置correclty__EVENTVALIDATION。得到正确的结果(如上所述),尽管我的EVENTVALIDATION在所有帖子中都具有相同的值。问题从我打到第11页时开始(不在ori中金网页)。之后,我总是重定向到主页。 – Jim