2017-12-25 16 views
-3

Ich brauche eine Post-Anforderung an diese URL senden:302 Redirect in xhr Anfrage

http://lastsecond.ir/hotels/ajax 

Sie die anderen Parameter, die von dieser Anfrage sehen hier senden:

formdata: 

filter_score: 
sort:reviewed_at 
duration:0 
page:1 
base_location_id:1 

request header: 

:authority:lastsecond.ir 
:method:POST 
:path:/hotels/ajax 
:scheme:https 
accept:*/* 
accept-encoding:gzip, deflate, br 
accept-language:en-US,en;q=0.9,fa;q=0.8,ja;q=0.7 
content-length:67 
content-type:application/x-www-form-urlencoded; charset=UTF-8 
cookie:_jsuid=2453861291; read_announcements=,11,11; _ga=GA1.2.2083988810.1511607903; _gid=GA1.2.1166842676.1513922852; XSRF-TOKEN=eyJpdiI6IlZ2TklPcnFWU3AzMlVVa0k3a2xcL2dnPT0iLCJ2YWx1ZSI6ImVjVmt2c05STWRTUnJod1IwKzRPNk4wS2lST0k1UTk2czZwZXJxT2FQNmppNkdUSFdPK29kU29RVHlXbm1McTlFSlM5VlIwbGNhVUozbXFBbld5c2tRPT0iLCJtYWMiOiI4YmNiMGQwMzdlZDgyZTE2YWNlMWY1YjdmMzViNDQwMmRjZGE4YjFmMmM1ZmUyNTQ0NmE1MGRjODFiNjMwMzMwIn0%3D; lastsecond-session=eyJpdiI6ImNZQjdSaHhQM1lZaFJIZzhJMWJXN0E9PSIsInZhbHVlIjoiK1NWdHJiUTdZQzBYeEsyUjE3QXFhUGJrQXBGcExDMVBXTjhpSVJLRlFnUjVqXC9USHBxNGVEZ3dwKzVGcG5yeU93VTZncG9wRGpvK0VpVnQ2b1ByVnh3PT0iLCJtYWMiOiI4NTFkYmQxZTFlMTMxOWFmZmU1ZjA1ZGZhNTMwNDFmZmU0N2FjMGVjZTg1OGU2NGE0YTNmMTc2MDA5NWM1Njg3In0%3D 
origin:https://lastsecond.ir 
referer:https://lastsecond.ir/hotels?score=&page=1&sort=reviewed_at&duration=0 
user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36 
x-csrf-token:oMpQTG0wN0YveJIk2WhkesvzjZE2FqHkDqPiW8Dy 
x-requested-with:XMLHttpRequest 

das Ergebnis dieses Codes Angenommen, dass es sich um eine JSON-Datei handelt, umleiten Sie die Anfrage an die entsprechende URL. Ich verwende scrapy mit Python Anfrage zu senden, hier ist scrapy Code:

class HotelsSpider(scrapy.Spider): 
    name = 'hotels' 
    allowed_domains = ['lastsecond.ir'] 
    start_urls = ['http://lastsecond.ir/hotels'] 

    def parse(self, response): 
     data = { 
      'filter_score': '', 
      'sort': 'reviewed_at', 
      'duration': '0', 
      'page': '1', 
      'base_location_id': '1' 
     } 
     headers = { 
      'user-agent': 'Mozilla/5.0', 
      'x-csrf-token': 'oMpQTG0wN0YveJIk2WhkesvzjZE2FqHkDqPiW8Dy', 
      'x-requested-with': 'XMLHttpRequest' 
     } 
     url = 'https://lastsecond.ir/hotels/ajax' 
     return FormRequest(
      url=url, 
      callback=self.parse_details, 
      formdata=data, 
      method="POST", 
      headers=headers, 
      dont_filter=True 
     ) 

    def parse_details(self, response): 
     data = response.body_as_unicode() 
     print(data) 
     #f = open('output.json', 'w') 
     #f.write(data) 
     #f.close() 

ich meinen Code geändert haben, so dass es die frische csrf-Token jedes Mal wird es eine Anforderung sendet:

class HotelsSpider(scrapy.Spider): 
    name = 'hotels' 
    allowed_domains = ['lastsecond.ir'] 
    start_urls = ['http://lastsecond.ir/hotels'] 

    def parse(self, response): 
     html = response.body_as_unicode() 
     start = html.find("var csrftoken = '") 
     start = start + len(b"var csrftoken = '") 
     end = html.find("';", start) 

     self.csrftoken = html[start:end] 

     print('csrftoken:', self.csrftoken) 
     yield self.ajax_request('1') 

    def ajax_request(self, page): 
     data = { 
      'filter_score': '', 
      'sort': 'reviewed_at', 
      'duration': '0', 
      'page': page, 
      'base_location_id': '1' 
     } 
     headers = { 
      'user-agent': 'Mozilla/5.0', 
      'x-csrf-token': self.csrftoken, 
      'x-requested-with': 'XMLHttpRequest' 
     } 
     url = 'https://lastsecond.ir/hotels/ajax' 
     return FormRequest(
      url=url, 
      callback=self.parse_details, 
      formdata=data, 
      method="POST", 
      headers=headers, 
      dont_filter=True 
     ) 

    def parse_details(self, response): 
     print(response.body_as_unicode()) 

jede Hilfe wäre willkommen.

+0

jede Anfrage braucht neue uniqe ''x-csrf-token'' - Sie können nicht immer das gleiche verwenden. Siehe meine Antwort auf die vorherige Frage - ich bekomme "GET", um ein neues "x-csrf-token" von "HTML" zu bekommen. – furas

+0

NIE Frage ändern. Jetzt passt meine Antwort nicht zu Ihrem Problem. Wenn Sie den Code geändert haben und weiterhin ein Problem haben, fügen Sie ihn an die ursprüngliche Frage an oder erstellen Sie eine neue Frage. – furas

+0

Ich reparierte die Frage wie Sie sagten, Entschuldigung für das Ändern der ursprünglichen Frage. Kannst du mich jetzt bitte führen? – Amirition

Antwort

0

Machen Sie eine illegale Anfrage?, Ist der einfachste Weg, es zu lernen, die Anfrage im Browser als Curl zu kopieren (F12 -> Netzwerk -> Rechtsklick auf Anfrage angeben -> Kopieren -> Als Curl kopieren), und konvertieren Sie es in Python-Sprache mit this tool (ohne Scrapy)

0

Ihr Fehler ist der gleiche 'x-csrf-token' in jeder Anfrage.

'x-csrf-token' ist eine Methode, um Bots/Skripte zu blockieren.

Wikipedia: Cross Site Request Forgery

Jedes Mal, wenn offene Seite in Browser-Portal generiert neue, uniqe 'x-csrf-token', die nur für kurze Zeit richtig sein können. Sie können nicht die gleiche 'x-csrf-token' die ganze Zeit verwenden.

Als Antwort auf die vorherige Frage mache ich GET Anfrage, Seite zu erhalten und zu finden X-CSRF-TOKEN.

Siehe self.csrftoken in Code

def parse(self, response): 
    print('url:', response.url) 

    html = response.body_as_unicode() 

    start = html.find("var csrftoken = '") 
    start = start + len(b"var csrftoken = '") 
    end = html.find("';" , start) 

    self.csrftoken = html[start:end] 

    print('csrftoken:', self.csrftoken) 

    yield self.create_ajax_request('1') 

Und später verwende ich dieses Token AJAX Anfragen zu lesen.

def create_ajax_request(self, page): 
    ''' 
    subfunction can't use `yield, it has to `return` Request to `parser` 
    and `parser` can use `yield` 
    ''' 

    print('yield page:', page) 

    url = 'https://lastsecond.ir/hotels/ajax' 

    headers = { 
     'X-CSRF-TOKEN': self.csrftoken, 
     'X-Requested-With': 'XMLHttpRequest', 
    } 

    params = { 
     'filter_score': '', 
     'sort': 'reviewed_at', 
     'duration': '0', 
     'page': page, 
     'base_location_id': '1', 
    } 

    return scrapy.FormRequest(url, 
     callback=self.parse_details, 
     formdata=params, 
     headers=headers, 
     dont_filter=True, 
    ) 
+0

danke für deine hilfreiche antwort, ich habe meinen code so bearbeitet, dass er jedes mal den neuen csrf token bekommt, aber immer noch 302 redirect und html response bekommt. – Amirition