Informationen aus Ajax Schaben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
overload
User
Beiträge: 13
Registriert: Dienstag 6. April 2021, 13:41

Hallo zusammen,

ich stehe vor folgendem Problem:

ich schreibe ein Skript was mir automatisch Sachen ins Netz zum verkaufen stellt. Die Sachen sind schon online vorgegeben und haben von der Webseite an sich eine productbase_id.
Diese id benötige ich um in meinen POST request mitzugeben, das Problem ist ich finde sie einfach nicht im normalen html code. Wenn ich die base_id in chrome suche wird mir folgender code rausgespuckt:

Code: Alles auswählen

function resetNotify() {
            $('.product .notify__me__wrapper .c-field').css('width', '67%');
            undoInputMessage($('#email'));
            $("#email").val('XXXXXXX@hotmail.com');
            $('#notify-me').show();
        }

        $('#notify-me').on('click', function () {
            $.ajax({
                type: "POST",
                url: 'https://restocks.net/de/product/notify-me',
                data: '_token=hyqEvjYg3K3NNpav0mK85ZR3WeB802UHmT6bX4MJ&email=' + $('#email').val() + '&baseproduct_id=10310&size_id=' + $('#size').val(),
                dataType: 'json',
                success: function (data) {
                    $('#notify-me').hide();
                    $('.product .notify__me__wrapper .c-field').css('width', '100%');
                    inputMessage($('#email'), 'Danke. Wir kümmern uns darum!');
                },
                error: function (data) {
                    if (typeof data.responseJSON.errors != 'undefined') {
                        showErrors(data.responseJSON.errors);
                    }
                },
            });
        });
Da ist die baseproduct_id versteckt die 10310.

Diese möchte ich mir gerne rausfischen um sie weiter zu benutzen, ich habe allerdings absolut keine Ahnung wie ich das anstellen so.

Habt ihr eine Idee für mich wie das gehen könnte? Hier noch der Link von der Seite direkt: https://restocks.net/de/p/adidas-yeezy- ... tail-light

Vielen dank für eure Hilfe, wünsche euch noch ein angenehmes Wochenende :D .
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@overload,
ich schreibe ein Skript was mir automatisch Sachen ins Netz zum verkaufen stellt.
Was hast du denn bisher versucht? An welcher Stelle in deinem Skript hast du Probleme?
overload
User
Beiträge: 13
Registriert: Dienstag 6. April 2021, 13:41

rogerb hat geschrieben: Samstag 14. August 2021, 18:21 @overload,
ich schreibe ein Skript was mir automatisch Sachen ins Netz zum verkaufen stellt.
Was hast du denn bisher versucht? An welcher Stelle in deinem Skript hast du Probleme?
Ich arbeite mit Bs4 und ziehe mir so alle relevanten Daten, bisher habe ich mir die baseproduct_id immer selber rauskopiert, aber es soll halt so laufen, dass ich nur noch den Link von dem Produkt einfüge als Input z.b. und er sich dann die baseproduct_id speichert und in den payload lädt. Allerdings habe ich echt überhaupt keine Ahnung wie ich hier vorgehen soll da ich aus so einem Teil von Code noch nie was gescraped habe. Bisher habe ich es nur mit beautifulsoup gemacht. Der Rest des Skriptes funktioniert auch ich möchte es nur noch automatisieren, da ich sonst am Ende mehr Arbeit habe als davor.
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Ich arbeite mit Bs4 und ziehe mir so alle relevanten Daten
Wenn du das mit allen anderen Daten schaffst, verstehe ich nicht ganz warum du es hier nicht hinbekommst.
Das ist ja auch nur Text in einem Script-Tag. Das ist also mit minimalen Python - Kenntnissen zu bewerkstelligen.
Aber wenn du uns den existierenden Code, wenigstens ausschnittweise zeigst, können wir dir zeigen was geändert bzw. ergänzt werden muss.
Benutzeravatar
__blackjack__
User
Beiträge: 14019
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@rogerb: Der Unterschied ist wahrscheinlich, dass die anderen Daten als HTML strukturiert sind und bs4 das halt versteht und man darin suchen/navigieren kann, während diese spezielle Information ebenfalls in strukturiertem Text steht, aber der ist JavaScript-Quelltext und da ist bs4 dann halt kein sinnvolles Werkzeug um da auf der *Struktur* zu operieren. Das ist halt eine relativ grosse Zeichenkette und entsprechend nicht so einfach robust zu verarbeiten wie das bei geparstem HTML der Fall ist.

Da ist man erst einmal wieder bei 0 was die Unterstützung durch Werkzeuge angeht und müsste/könnte versuchen das mit einem regulären Ausdruck zu erschlagen, wo bei strukturierten Daten ja sonst (zurecht) immer deutlich von *abgeraten* wird.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

Der Unterschied ist wahrscheinlich, dass die anderen Daten als HTML ...
Genau, aber ich jedenfalls, werde jetzt kein fertiges Script schreiben um das herauszufiltern. Daher die Frage wie weit ist @overload schon gekommen ist und was ist noch unklar.

Bei JavaScript kommt man mit BS4 bis zum Script-Tag, aber nicht weiter. Dann hat man JavaScript in Form eines Textblocks. Der zu suchende Ausdruck sieht anscheinend immer so aus: &baseproduct_id=10310
Die gesuchte Zahl steht also immer hinter dem "=" Zeichen.
overload
User
Beiträge: 13
Registriert: Dienstag 6. April 2021, 13:41

__blackjack__ hat geschrieben: Sonntag 15. August 2021, 14:06 Da ist man erst einmal wieder bei 0 was die Unterstützung durch Werkzeuge angeht und müsste/könnte versuchen das mit einem regulären Ausdruck zu erschlagen, wo bei strukturierten Daten ja sonst (zurecht) immer deutlich von *abgeraten* wird.
Was ich auch komisch finde, das ich nirgendwo diese product_id finde. Normal muss ich die doch auch im ganz normalen HTML finden, sowie ich auch den _token finde etc. . Diese Information muss doch auch irgendwo stehen um sie dort hineinzupacken oder liege ich da falsch?
Wenn du das mit allen anderen Daten schaffst, verstehe ich nicht ganz warum du es hier nicht hinbekommst.
Das ist ja auch nur Text in einem Script-Tag. Das ist also mit minimalen Python - Kenntnissen zu bewerkstelligen.
Aber wenn du uns den existierenden Code, wenigstens ausschnittweise zeigst, können wir dir zeigen was geändert bzw. ergänzt werden muss.
Also ich ziehe mir Daten z.b. immer so:

Code: Alles auswählen

with requests.session() as s:
    url = "https://restocks.net/de/login"
    r = s.get(url, headers=headers)
    soup = BeautifulSoup(r.content, "html5lib")
    token = soup.find("input", attrs={"name": "_token"})["value"]
    print(token)
    login_data = {
        "_token": token,
        "email": "XXXX@hotmail.com",
        "password": "XXXX"}

    r = s.post("https://restocks.net/de/login", data=login_data, headers = headers)
    
hier z.B. benötige ich den token zum login, diesen finde ich ganz normal im HTML Quelltext und kann ihn mir ziehen, aber hier habe ich ja eine ganz andere Struktur an text.
Den Token finde ich in folgender Zeile:

Code: Alles auswählen

<input type="hidden" name="_token" value="uh1Evo5vN7gpHPvpYsl8oqf20N7oNssT8xmkpqLc">
Aber die baseproduct_id gibt es in dieser Form einfach nicht und irgendwie muss es ja möglich sein dass zu kopieren.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du liegst falsch. Rein technisch gibt es keinen Grund, warum wichtige Daten nicht einfach in den JS-Quelltext kodiert sein sollten. Und so sieht’s ja auch konkret aus. Du kannst die da mit den benannten Mitteln extrahieren - String-Methoden, reguläre Ausdrücke, oder ganz fancy einen JS-Parser bemühen.

Alternativ kann man auch Selenium zur Steuerung eines Browsers benutzen. Der führt das js dann einfach aus.
overload
User
Beiträge: 13
Registriert: Dienstag 6. April 2021, 13:41

rogerb hat geschrieben: Sonntag 15. August 2021, 14:42
Der Unterschied ist wahrscheinlich, dass die anderen Daten als HTML ...
Genau, aber ich jedenfalls, werde jetzt kein fertiges Script schreiben um das herauszufiltern. Daher die Frage wie weit ist @overload schon gekommen ist und was ist noch unklar.

Bei JavaScript kommt man mit BS4 bis zum Script-Tag, aber nicht weiter. Dann hat man JavaScript in Form eines Textblocks. Der zu suchende Ausdruck sieht anscheinend immer so aus: &baseproduct_id=10310
Die gesuchte Zahl steht also immer hinter dem "=" Zeichen.
Leider bin ich da an meine derzeitigen grenzen gestoßen, ich komme bis dahin, mir den gesamten Quelltext zu ziehen, aber ich weiss absolut nicht wir ich den erst herausfiltern soll. Ein gescheites Tutorial finde ich leider nicht.

Code: Alles auswählen

shoes = s.get("https://restocks.net/de/p/adidas-yeezy-boost-350-v2-tail-light")
    soup = BeautifulSoup(shoes.content, "html5lib")
    print(soup)
    
Das habe ich jetzt um mir den content zu ziehen. Weiter komme ich nicht.
Benutzeravatar
Whitie
User
Beiträge: 217
Registriert: Sonntag 4. Juni 2006, 12:39
Wohnort: Schulzendorf

Du könntest es (wie weiter oben schon vorgeschlagen) mit dem re Modul versuchen.

Code: Alles auswählen

import re

with requests.session() as s:
    url = "https://restocks.net/de/p/adidas-yeezy-boost-350-v2-tail-light"
    r = s.get(url, headers=headers)
    match = re.search(r"&baseproduct_id=(\d+)", r.content)
    if match:
        print(match.group(1))
Nicht robust, funktioniert aber solange die Seite nicht geändert wird (z. B. die ID in einer Javascript Variable liegt).

Gruß
Whitie
Benutzeravatar
snafu
User
Beiträge: 6854
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Was für Schaben? Sind wir hier bei Men In Black? 😡
overload
User
Beiträge: 13
Registriert: Dienstag 6. April 2021, 13:41

Whitie hat geschrieben: Sonntag 15. August 2021, 19:03 Du könntest es (wie weiter oben schon vorgeschlagen) mit dem re Modul versuchen.

Code: Alles auswählen

import re

with requests.session() as s:
    url = "https://restocks.net/de/p/adidas-yeezy-boost-350-v2-tail-light"
    r = s.get(url, headers=headers)
    match = re.search(r"&baseproduct_id=(\d+)", r.content)
    if match:
        print(match.group(1))
Nicht robust, funktioniert aber solange die Seite nicht geändert wird (z. B. die ID in einer Javascript Variable liegt).

Gruß
Whitie
Oh das ist perfekt, bei mir funktioniert es aber nur so:

Code: Alles auswählen

with requests.session() as s:
    r = s.get(url)
    match = re.search(b"&baseproduct_id=(\d+)", r.content)

    if match:
        product_id = match.group(1)
        product_id = str(product_id)
        product_id = product_id.replace("b","")
        product_id = product_id.replace("'","")
    print(product_id)
aber ist ja auch egal, solange es geht ist es die Hauptsache, vielen dank! Dann weiss ich wo ich jetzt ansetzen muss und schaue mir das ganze re Modul näher an :)!
Benutzeravatar
__blackjack__
User
Beiträge: 14019
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@overload: Nein das ist nicht egal. Man wandelt keine Objekte in Zeichenketten um und stümpert dann da mit Zeichenkettenoperationen auf der Repräsentation eines Bytes-Objekts. `r.content` ist falsch — das sind Bytes. Du willst `r.text`. Und Namen verwenden die nicht nur aus einem Buchstaben bestehen. `session` und `response`.

Das letzte `print()` ist falsch eingerückt. Das gehört in den ``if``-Zweig. Wenn der überhaupt nicht betreten wird, dann ist `product_id` undefiniert und die letzte Zeile fällt auf die Nase und löst eine Ausnahme aus.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
overload
User
Beiträge: 13
Registriert: Dienstag 6. April 2021, 13:41

Das mit dem print() habe ich auch sofort festgestellt dass ich da Mist gebaut habe, jetzt funktioniert es auch mit dem r.text . Vielen dank für die Erklärung!
Benutzeravatar
Whitie
User
Beiträge: 217
Registriert: Sonntag 4. Juni 2006, 12:39
Wohnort: Schulzendorf

Ich arbeite mit requests meist mit JSON, deshalb hatte ich nicht geschaut, was r.content genau liefert. Natürlich sollte man nicht mit den Bytes arbeiten, sondern (wie __blackjack__ schrieb) mit Text (r.text). Ich würde mir da auch eine aussagekräftige Ausgabe machen, wenn es keinen Match gibt. Dann muss man immer prüfen, ob sich die Seite geändert hat und das Skript angepasst werden muss.

Gruß
Antworten