2015-09-06 4 views
5

मैं वेबपृष्ठ डेटा प्राप्त करने के लिए htmlagility का उपयोग करता हूं लेकिन मैंने ddos ​​के लिए www.cloudflare.com सुरक्षा का उपयोग करके पृष्ठ के साथ सब कुछ करने की कोशिश की। एचटीएमएलएगिलिटी में रीडायरेक्ट पेज को संभालना संभव नहीं है क्योंकि वे मेटा के साथ रीडायरेक्ट नहीं करते हैं और न ही मुझे लगता है कि वे जांच कर रहे हैं कि क्या आप पहले से ही एक कुकी के साथ चेक कर रहे हैं जिसे मैं सी # के साथ अनुकरण करने में असफल रहा। जब मुझे पृष्ठ मिलता है, तो HTML कोड लैंडिंग क्लॉडफ़्लेयर पृष्ठ से होता है।क्लाउडफ्लेयर डीडीओएस पोर्ट्रेशन के साथ पेज से एचटीएमएल कैसे प्राप्त कर सकता हूं?

+0

कुकीज़ पास करना http: // stackoverflow।com/a/20478716/736079 – jessehouwing

+0

आप ब्राउज़र सत्र वर्ग का भी यहां समझाए गए अनुसार उपयोग कर सकते हैं: http://refactoringaspnet.blogspot.nl/2010/04/using-htmlagilitypack-to-get-and-post.html – jessehouwing

उत्तर

-1

उपयोग WebClient पेज के HTML पाने के लिए,
मैं कक्षा जो कुकीज़ संभालती भी
बस निर्माता में CookieContainer उदाहरण पारित निम्नलिखित लिखा था।

using System; 
using System.Collections.Generic; 
using System.Configuration; 
using System.Linq; 
using System.Net; 
using System.Text; 

namespace NitinJS 
{ 
    public class SmsWebClient : WebClient 
    { 
     public SmsWebClient(CookieContainer container, Dictionary<string, string> Headers) 
      : this(container) 
     { 
      foreach (var keyVal in Headers) 
      { 
       this.Headers[keyVal.Key] = keyVal.Value; 
      } 
     } 
     public SmsWebClient(bool flgAddContentType = true) 
      : this(new CookieContainer(), flgAddContentType) 
     { 

     } 
     public SmsWebClient(CookieContainer container, bool flgAddContentType = true) 
     { 
      this.Encoding = Encoding.UTF8; 
      System.Net.ServicePointManager.Expect100Continue = false; 
      ServicePointManager.MaxServicePointIdleTime = 2000; 
      this.container = container; 

      if (flgAddContentType) 
       this.Headers["Content-Type"] = "application/json";//"application/x-www-form-urlencoded"; 
      this.Headers["Accept"] = "application/json, text/javascript, */*; q=0.01";// "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; 
      //this.Headers["Accept-Encoding"] = "gzip, deflate"; 
      this.Headers["Accept-Language"] = "en-US,en;q=0.5"; 
      this.Headers["User-Agent"] = "Mozilla/5.0 (Windows NT 6.1; rv:23.0) Gecko/20100101 Firefox/23.0"; 
      this.Headers["X-Requested-With"] = "XMLHttpRequest"; 
      //this.Headers["Connection"] = "keep-alive"; 
     } 

     private readonly CookieContainer container = new CookieContainer(); 

     protected override WebRequest GetWebRequest(Uri address) 
     { 
      WebRequest r = base.GetWebRequest(address); 
      var request = r as HttpWebRequest; 
      if (request != null) 
      { 
       request.CookieContainer = container; 
       request.Timeout = 3600000; //20 * 60 * 1000 
      } 
      return r; 
     } 

     protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result) 
     { 
      WebResponse response = base.GetWebResponse(request, result); 
      ReadCookies(response); 
      return response; 
     } 

     protected override WebResponse GetWebResponse(WebRequest request) 
     { 
      WebResponse response = base.GetWebResponse(request); 
      ReadCookies(response); 
      return response; 
     } 

     private void ReadCookies(WebResponse r) 
     { 
      var response = r as HttpWebResponse; 
      if (response != null) 
      { 
       CookieCollection cookies = response.Cookies; 
       container.Add(cookies); 
      } 
     } 
    } 
} 

उपयोग:

CookieContainer cookies = new CookieContainer(); 
SmsWebClient client = new SmsWebClient(cookies); 
string html = client.DownloadString("http://www.google.com"); 
+0

लेकिन isn ' यहाँ समस्या पूरी तरह से एक अलग है? वह पृष्ठ तक नहीं पहुंच सकता क्योंकि क्लाउडफ्लेयर की एंटी-डीडीओएस सुरक्षा उसे दूसरे पृष्ठ पर रीडायरेक्ट करती है। एक वेब क्लाइंट क्लास का उपयोग करना जो स्वचालित रूप से कुकीज़ संग्रहीत करता है, उसकी मदद नहीं करता है। या यह 'है। हेडर ["एक्स-अनुरोधित-साथ"] = "XMLHttpRequest";' क्लाउडफ्लेयर के एंटी-डीडीओएस सुरक्षा की पूरी तरह से बाधित है? –

+0

'हेडर' को संशोधित करने की आवश्यकता है, मैं सुझाव देता हूं कि ओपी फिडलर का उपयोग करके अपने ब्राउज़र से अनुरोध लॉग इन करें और उसके अनुसार हेडर संशोधित करें। मुझे आशा है कि इस वर्ग की समस्या का उपयोग करके हल किया जाएगा। –

+0

यह समस्या सिर्फ कुकीज़ के बारे में नहीं है। जैसा कि @MaximilianGerhardt ने अपने उत्तर में बताया, क्लाउडफ्लेयर के एंटी-डीडीओएस उपाय को बाईपास करने के लिए आपको एक जावास्क्रिप्ट चुनौती हल करना होगा। –

5

मैं भी कुछ समय पहले इस समस्या का सामना करना पड़ा। वास्तविक समाधान क्लाउडफ्लर वेबसाइटों को चुनौती देने का चुनौती हल करेगा (आपको जावास्क्रिप्ट का उपयोग करके एक सही उत्तर की गणना करने की आवश्यकता है, इसे वापस भेजें, और फिर आपको एक कुकी/टोकन प्राप्त होता है जिसके साथ आप वेबसाइट देखना जारी रख सकते हैं)। इसलिए सभी आप सामान्य रूप से मिलेगा तरह

cloudflare

अंत में एक पेज है, मैं बस एक खोल-निष्पादित के साथ एक अजगर स्क्रिप्ट कहा जाता है। मैंने this github fork के भीतर प्रदान किए गए मॉड्यूल का उपयोग किया। यह सी # एस्वेल में क्लाउडफ्लेयर एंटी-डीडीओएस पृष्ठ की छेड़छाड़ को लागू करने के लिए एक प्रारंभिक बिंदु के रूप में कार्य कर सकता है।

एफवाईआई, मैंने अपने व्यक्तिगत उपयोग के लिए लिखी गई पायथन लिपि सिर्फ एक फ़ाइल में कुकी लिखी है। मैंने बाद में सी # का उपयोग करके पढ़ा और इसे CookieJar में स्टोर किया ताकि सी # के भीतर पृष्ठ ब्राउज़ करना जारी रखा जा सके।

#!/usr/bin/env python 
import cfscrape 
import sys 

scraper = cfscrape.create_scraper() # returns a requests.Session object 
fd = open("cookie.txt", "w") 
c = cfscrape.get_cookie_string(sys.argv[1]) 
fd.write(str(c)) 
fd.close() 
print(c) 

संपादित करें: इसे दोहराने के लिए, कुकीज़ के साथ केवल इतना ही छोटा है! क्लाउडफ्लॉवर आपको जावास्क्रिप्ट कमांड का उपयोग करके एक वास्तविक चुनौती हल करने के लिए मजबूर करता है। कुकी को स्वीकार करने और बाद में इसका उपयोग करना उतना आसान नहीं है। चुनौती को हल करने के लिए https://github.com/Anorov/cloudflare-scrape/blob/master/cfscrape/init.py और जावास्क्रिप्ट अनुकरण की ~ 40 पंक्तियां देखें।

EDIT2: इसके बजाय संरक्षण नाकाम करने के लिए कुछ लेखन की, मैं भी लोगों को एक पूरी तरह से विकसित ब्राउज़र-वस्तु का उपयोग कर देखा है वेबसाइट पर जाएं और कुछ घटनाओं जब करने के लिए सदस्यता के लिए (इस नहीं एक बिना सिर ब्राउज़र है) पेज लोड हो गया है। एक infinetly छोटी ब्राउज़र विंडो बनाने और appropiate घटनाओं की सदस्यता लेने के लिए WebBrowser कक्षा का उपयोग करें।

संपादित 3: ठीक है, मैंने वास्तव में ऐसा करने के लिए सी # तरीका लागू किया। यह नेट के लिए जावास्क्रिप्ट इंजन Jint, के माध्यम से https://www.nuget.org/packages/Jint

कुकी हैंडलिंग कोड बदसूरत है क्योंकि कभी-कभी HttpResponse वर्ग कुकीज़ को लेने नहीं होगा उपलब्ध उपयोग करता है, हालांकि एक हैडर Set-Cookie अनुभाग में शामिल है।

using System; 
using System.Net; 
using System.IO; 
using System.Text.RegularExpressions; 
using System.Web; 
using System.Collections; 
using System.Threading; 

namespace Cloudflare_Evader 
{ 
    public class CloudflareEvader 
    { 
     /// <summary> 
     /// Tries to return a webclient with the neccessary cookies installed to do requests for a cloudflare protected website. 
     /// </summary> 
     /// <param name="url">The page which is behind cloudflare's anti-dDoS protection</param> 
     /// <returns>A WebClient object or null on failure</returns> 
     public static WebClient CreateBypassedWebClient(string url) 
     { 
      var JSEngine = new Jint.Engine(); //Use this JavaScript engine to compute the result. 

      //Download the original page 
      var uri = new Uri(url); 
      HttpWebRequest req =(HttpWebRequest) WebRequest.Create(url); 
      req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0"; 
      //Try to make the usual request first. If this fails with a 503, the page is behind cloudflare. 
      try 
      { 
       var res = req.GetResponse(); 
       string html = ""; 
       using (var reader = new StreamReader(res.GetResponseStream())) 
        html = reader.ReadToEnd(); 
       return new WebClient(); 
      } 
      catch (WebException ex) //We usually get this because of a 503 service not available. 
      { 
       string html = ""; 
       using (var reader = new StreamReader(ex.Response.GetResponseStream())) 
        html = reader.ReadToEnd(); 
       //If we get on the landing page, Cloudflare gives us a User-ID token with the cookie. We need to save that and use it in the next request. 
       var cookie_container = new CookieContainer(); 
       //using a custom function because ex.Response.Cookies returns an empty set ALTHOUGH cookies were sent back. 
       var initial_cookies = GetAllCookiesFromHeader(ex.Response.Headers["Set-Cookie"], uri.Host); 
       foreach (Cookie init_cookie in initial_cookies) 
        cookie_container.Add(init_cookie); 

       /* solve the actual challenge with a bunch of RegEx's. Copy-Pasted from the python scrapper version.*/ 
       var challenge = Regex.Match(html, "name=\"jschl_vc\" value=\"(\\w+)\"").Groups[1].Value; 
       var challenge_pass = Regex.Match(html, "name=\"pass\" value=\"(.+?)\"").Groups[1].Value; 

       var builder = Regex.Match(html, @"setTimeout\(function\(\){\s+(var t,r,a,f.+?\r?\n[\s\S]+?a\.value =.+?)\r?\n").Groups[1].Value; 
       builder = Regex.Replace(builder, @"a\.value =(.+?) \+ .+?;", "$1"); 
       builder = Regex.Replace(builder, @"\s{3,}[a-z](?: = |\.).+", ""); 

       //Format the javascript.. 
       builder = Regex.Replace(builder, @"[\n\\']", ""); 

       //Execute it. 
       long solved = long.Parse(JSEngine.Execute(builder).GetCompletionValue().ToObject().ToString()); 
       solved += uri.Host.Length; //add the length of the domain to it. 

       Console.WriteLine("***** SOLVED CHALLENGE ******: " + solved); 
       Thread.Sleep(3000); //This sleeping IS requiered or cloudflare will not give you the token!! 

       //Retreive the cookies. Prepare the URL for cookie exfiltration. 
       string cookie_url = string.Format("{0}://{1}/cdn-cgi/l/chk_jschl", uri.Scheme, uri.Host); 
       var uri_builder = new UriBuilder(cookie_url); 
       var query = HttpUtility.ParseQueryString(uri_builder.Query); 
       //Add our answers to the GET query 
       query["jschl_vc"] = challenge; 
       query["jschl_answer"] = solved.ToString(); 
       query["pass"] = challenge_pass; 
       uri_builder.Query = query.ToString(); 

       //Create the actual request to get the security clearance cookie 
       HttpWebRequest cookie_req = (HttpWebRequest) WebRequest.Create(uri_builder.Uri); 
       cookie_req.AllowAutoRedirect = false; 
       cookie_req.CookieContainer = cookie_container; 
       cookie_req.Referer = url; 
       cookie_req.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0"; 
       //We assume that this request goes through well, so no try-catch 
       var cookie_resp = (HttpWebResponse)cookie_req.GetResponse(); 
       //The response *should* contain the security clearance cookie! 
       if (cookie_resp.Cookies.Count != 0) //first check if the HttpWebResponse has picked up the cookie. 
        foreach (Cookie cookie in cookie_resp.Cookies) 
         cookie_container.Add(cookie); 
       else //otherwise, use the custom function again 
       { 
        //the cookie we *hopefully* received here is the cloudflare security clearance token. 
        if (cookie_resp.Headers["Set-Cookie"] != null) 
        { 
         var cookies_parsed = GetAllCookiesFromHeader(cookie_resp.Headers["Set-Cookie"], uri.Host); 
         foreach (Cookie cookie in cookies_parsed) 
          cookie_container.Add(cookie); 
        } 
        else 
        { 
         //No security clearence? something went wrong.. return null. 
         //Console.WriteLine("MASSIVE ERROR: COULDN'T GET CLOUDFLARE CLEARANCE!"); 
         return null; 
        } 
       } 
       //Create a custom webclient with the two cookies we already acquired. 
       WebClient modedWebClient = new WebClientEx(cookie_container); 
       modedWebClient.Headers.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0"); 
       modedWebClient.Headers.Add("Referer", url); 
       return modedWebClient; 
      } 
     } 

     /* Credit goes to https://stackoverflow.com/questions/15103513/httpwebresponse-cookies-empty-despite-set-cookie-header-no-redirect 
      (user https://stackoverflow.com/users/541404/cameron-tinker) for these functions 
     */ 
     public static CookieCollection GetAllCookiesFromHeader(string strHeader, string strHost) 
     { 
      ArrayList al = new ArrayList(); 
      CookieCollection cc = new CookieCollection(); 
      if (strHeader != string.Empty) 
      { 
       al = ConvertCookieHeaderToArrayList(strHeader); 
       cc = ConvertCookieArraysToCookieCollection(al, strHost); 
      } 
      return cc; 
     } 

     private static ArrayList ConvertCookieHeaderToArrayList(string strCookHeader) 
     { 
      strCookHeader = strCookHeader.Replace("\r", ""); 
      strCookHeader = strCookHeader.Replace("\n", ""); 
      string[] strCookTemp = strCookHeader.Split(','); 
      ArrayList al = new ArrayList(); 
      int i = 0; 
      int n = strCookTemp.Length; 
      while (i < n) 
      { 
       if (strCookTemp[i].IndexOf("expires=", StringComparison.OrdinalIgnoreCase) > 0) 
       { 
        al.Add(strCookTemp[i] + "," + strCookTemp[i + 1]); 
        i = i + 1; 
       } 
       else 
        al.Add(strCookTemp[i]); 
       i = i + 1; 
      } 
      return al; 
     } 

     private static CookieCollection ConvertCookieArraysToCookieCollection(ArrayList al, string strHost) 
     { 
      CookieCollection cc = new CookieCollection(); 

      int alcount = al.Count; 
      string strEachCook; 
      string[] strEachCookParts; 
      for (int i = 0; i < alcount; i++) 
      { 
       strEachCook = al[i].ToString(); 
       strEachCookParts = strEachCook.Split(';'); 
       int intEachCookPartsCount = strEachCookParts.Length; 
       string strCNameAndCValue = string.Empty; 
       string strPNameAndPValue = string.Empty; 
       string strDNameAndDValue = string.Empty; 
       string[] NameValuePairTemp; 
       Cookie cookTemp = new Cookie(); 

       for (int j = 0; j < intEachCookPartsCount; j++) 
       { 
        if (j == 0) 
        { 
         strCNameAndCValue = strEachCookParts[j]; 
         if (strCNameAndCValue != string.Empty) 
         { 
          int firstEqual = strCNameAndCValue.IndexOf("="); 
          string firstName = strCNameAndCValue.Substring(0, firstEqual); 
          string allValue = strCNameAndCValue.Substring(firstEqual + 1, strCNameAndCValue.Length - (firstEqual + 1)); 
          cookTemp.Name = firstName; 
          cookTemp.Value = allValue; 
         } 
         continue; 
        } 
        if (strEachCookParts[j].IndexOf("path", StringComparison.OrdinalIgnoreCase) >= 0) 
        { 
         strPNameAndPValue = strEachCookParts[j]; 
         if (strPNameAndPValue != string.Empty) 
         { 
          NameValuePairTemp = strPNameAndPValue.Split('='); 
          if (NameValuePairTemp[1] != string.Empty) 
           cookTemp.Path = NameValuePairTemp[1]; 
          else 
           cookTemp.Path = "/"; 
         } 
         continue; 
        } 

        if (strEachCookParts[j].IndexOf("domain", StringComparison.OrdinalIgnoreCase) >= 0) 
        { 
         strPNameAndPValue = strEachCookParts[j]; 
         if (strPNameAndPValue != string.Empty) 
         { 
          NameValuePairTemp = strPNameAndPValue.Split('='); 

          if (NameValuePairTemp[1] != string.Empty) 
           cookTemp.Domain = NameValuePairTemp[1]; 
          else 
           cookTemp.Domain = strHost; 
         } 
         continue; 
        } 
       } 

       if (cookTemp.Path == string.Empty) 
        cookTemp.Path = "/"; 
       if (cookTemp.Domain == string.Empty) 
        cookTemp.Domain = strHost; 
       cc.Add(cookTemp); 
      } 
      return cc; 
     } 
    } 

    /*Credit goes to https://stackoverflow.com/questions/1777221/using-cookiecontainer-with-webclient-class 
(user https://stackoverflow.com/users/129124/pavel-savara) */ 
    public class WebClientEx : WebClient 
    { 
     public WebClientEx(CookieContainer container) 
     { 
      this.container = container; 
     } 

     public CookieContainer CookieContainer 
     { 
      get { return container; } 
      set { container = value; } 
     } 

     private CookieContainer container = new CookieContainer(); 

     protected override WebRequest GetWebRequest(Uri address) 
     { 
      WebRequest r = base.GetWebRequest(address); 
      var request = r as HttpWebRequest; 
      if (request != null) 
      { 
       request.CookieContainer = container; 
      } 
      return r; 
     } 

     protected override WebResponse GetWebResponse(WebRequest request, IAsyncResult result) 
     { 
      WebResponse response = base.GetWebResponse(request, result); 
      ReadCookies(response); 
      return response; 
     } 

     protected override WebResponse GetWebResponse(WebRequest request) 
     { 
      WebResponse response = base.GetWebResponse(request); 
      ReadCookies(response); 
      return response; 
     } 

     private void ReadCookies(WebResponse r) 
     { 
      var response = r as HttpWebResponse; 
      if (response != null) 
      { 
       CookieCollection cookies = response.Cookies; 
       container.Add(cookies); 
      } 
     } 
    } 
} 

फ़ंक्शन अंदर हल की गई चुनौतियों और कुकीज़ के साथ एक वेब क्लाइंट लौटाएगा। आप इसे निम्नानुसार उपयोग कर सकते हैं:

static void Main(string[] args) 
{ 
    WebClient client = null; 
    while (client == null) 
    { 
     Console.WriteLine("Trying.."); 
     client = CloudflareEvader.CreateBypassedWebClient("http://anilinkz.tv"); 
    } 
    Console.WriteLine("Solved! We're clear to go"); 
     Console.WriteLine(client.DownloadString("http://anilinkz.tv/anime-list")); 

    Console.ReadLine(); 
} 
+2

मुझे हाल ही में एक ही समस्या को हल करना पड़ा। एक [समाधान] के रूप में (https://github.com/elcattivo/CloudFlareUtilities), मैंने .NET के लिए एक छोटी पोर्टेबल क्लास लाइब्रेरी लिखी है जो एक प्रतिनिधिमंडल प्रदान करता है जो स्वचालित रूप से जेएस चुनौती का प्रबंधन करता है ताकि आप HttpClient क्लास का उपयोग कर संरक्षित साइट तक पहुंच सकें क्लाउडफ्लेयर की सुरक्षा के बारे में चिंता किए बिना। यह किसी भी जेएस इंजन पर निर्भर नहीं है। –

संबंधित मुद्दे