Nie można pozwolić, aby mój skrypt automatycznie wygenerował kilka wartości do użycia w ładunku

10

Utworzyłem skrypt, aby pobrać elementy HTML ze strony docelowej, wysyłając następnie dwa żądania https. Mój skrypt potrafi to zrobić bezbłędnie. Musiałem jednak skopiować cztery wartości z narzędzi chrome dev, aby wypełnić cztery klucze payloadw celu wysłania ostatecznych żądań HTTP do strony docelowej. To jest link początkowy, a poniżej znajduje się opis, w jaki sposób mogłem dotrzeć do strony docelowej.

  1. Kliknij Find Hotelprzycisk (nie trzeba zmieniać dat, jeśli chek-outdata jest domyślnie co najmniej o jeden dzień dłuższa niż check-indata).
  2. Zaznacz pole jak na obrazku poniżej i naciśnij Book Nowprzycisk tuż nad nim. Teraz powinien automatycznie doprowadzić Cię do strony docelowej.
  3. Po osiągnięciu strony docelowej zatytułowanej jako Enter Guest Details, przeanalizuj stamtąd elementy HTML

wprowadź opis zdjęcia tutaj

Próbowałem z (działającym):

import requests
from bs4 import BeautifulSoup

url = 'https://booking.discoverqatar.qa/SearchHandler.aspx?'
second_url = 'https://booking.discoverqatar.qa/PassengerDetails.aspx?'

params = {
    'Module':'H','txtCity':'','hdnCity':'2947','txtHotel':'','hdnHotel':'',
    'fromDate':'05/11/2019','toDate':'07/11/2019','selZone':'','minSelPrice':'',
    'maxSelPrice':'','roomConfiguration':'2|0|','noOfRooms':'1',
    'hotelStandardArray':'63,60,54,50,52,51','CallFrom':'','DllNationality':'-1',
    'HdnNoOfRooms':'-1','SourceXid':'MTEzNzg=','mdx':''
}

payload = {
    'CallFrom':'MToxNjozOCBQTXxCMkN8MToxNjozOCBQTQ==',
    'Btype':'MToxNjozOCBQTXxBfDE6MTY6MzggUE0=',
    'PaxConfig':'MToxNjozOCBQTXwyfDB8MnwwfHwxOjE2OjM4IFBN',
    'usid':'MToxNjozOCBQTXxoZW54dmkzcWVnc3J3cXpld2lsa2ZwMm18MToxNjozOCBQTQ=='  
}

with requests.Session() as s:
    r = s.get(url,params=params,headers={"User-agent":"Mozilla/5.0"})
    res = s.get(second_url,params=payload,headers={
        "User-agent":"Mozilla/5.0",
        "Referer":r.url
        })
    soup = BeautifulSoup(res.text,'lxml')
    print(soup)

W powyższym skrypcie mam skopiowane i wklejone wartość CallFrom, Btype, PaxConfiga usidod dev narzędzi do użytku wewnątrz payload.

Jak mogę automatycznie wpisać wartości, które będą używane w ramach ładunku?

MITHU
źródło
Czy odpowiedź Kamoo nie jest wystarczająca? Myślę, że mogę uzyskać wyniki, postępując zgodnie z ich instrukcjami.
tmadam
Cześć @tmadam, dziękuję za twoją interwencję. Tak, odpowiedź Kamoo wyjaśnia, w jaki sposób mogę uzyskać wyniki, ale bardzo wątpię, czy mogę sam ją zaimplementować w powyższym skrypcie i to jest właśnie powód, dla którego ustawiłem nagrodę za uzyskanie pełnoprawnej odpowiedzi. Dzięki.
MITHU,
O, rozumiem. Jestem pewien, że @Kamoo dostarczy kod, jeśli zostanie o to poproszony.
tmadam
@MITHU Zaktualizowałem swoją odpowiedź, pamiętaj, że Btypemoże to być wartość dynamiczna odpowiadająca opcjom wybranym od pierwszego kroku. PaxConfigmoże również mieć inny format, jeśli pasażerowie obejmują dzieci.
Kamoo,

Odpowiedzi:

5

Parametry wysyłane do drugiego żądania są kodowane w standardzie Base64 , po dekodowaniu są to:

    'CallFrom':'1:16:38 PM|B2C|1:16:38 PM',
    'Btype':'1:16:38 PM|A|1:16:38 PM',
    'PaxConfig':'1:16:38 PM|2|0|2|0||1:16:38 PM',
    'usid':'1:16:38 PM|henxvi3qegsrwqzewilkfp2m|1:16:38 PM'  

Na pierwszy rzut oka już widać, że są w wzorach:

$date|$param|$date

Gdzie $datejest aktualny czas w formacie utc_ts_now.strftime("%I:%M:%S %p").

W przypadku $paramsekcji tych czterech parametrów, myślę, że należy to naprawić CallFromi Btype, usidjest kluczem sesji , można go łatwo znaleźć w poprzedniej odpowiedzi.

PaxConfigliczy się gość, jest on związany z roomConfigurationtobą wysłanym w pierwszej prośbie.

Aby zautomatyzować drugie żądanie, najpierw należy wygenerować zdekodowaną wartość dla każdego parametru, a następnie zakodować je Base64.

Aktualizacja:

#!/usr/bin/env python3.7
import base64
from datetime import datetime

import requests


def first_request(session, params):
    url = 'https://booking.discoverqatar.qa/SearchHandler.aspx'
    r = session.get(url, params=params)
    return r


def second_request(session, params):
    url = 'https://booking.discoverqatar.qa/PassengerDetails.aspx'
    r = session.get(url, params=params)
    return r


def main():
    params1 = {
        'Module':             'H',
        'txtCity':            '',
        'hdnCity':            '2947',
        'txtHotel':           '',
        'hdnHotel':           '',
        'fromDate':           '05/11/2019',
        'toDate':             '07/11/2019',
        'selZone':            '',
        'minSelPrice':        '',
        'maxSelPrice':        '',
        'roomConfiguration':  '2|0|',
        'noOfRooms':          '1',
        'hotelStandardArray': '63,60,54,50,52,51',
        'CallFrom':           '',
        'DllNationality':     '-1',
        'HdnNoOfRooms':       '-1',
        'SourceXid':          'MTEzNzg=',
        'mdx':                ''
    }
    session = requests.Session()
    _ = first_request(session, params1)
    asp_session = session.cookies.get("ASP.NET_SessionId")

    params2 = {
        # Could related to options "Available" / "On Request"
        "Btype":     "A",

        # Try out other guest counts to make sure
        "PaxConfig": params1["roomConfiguration"] * 2,

        "CallFrom": "B2C",
        "usid":     asp_session
    }
    date = datetime.utcnow().strftime("%I:%M:%S %p")
    for k, v in params2.items():
        v = "|".join([date, v, date])
        v = base64.b64encode(bytes(v, "utf-8")).decode("utf-8")
        params2[k] = v
    r = second_request(session, params2)
    print(r.text)


if __name__ == '__main__':
    main()
Kamoo
źródło