Ajax Request mittels Pythons Request Libary

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
bob1704
User
Beiträge: 27
Registriert: Dienstag 5. März 2013, 21:28

Hallo zusammen,
wenn man https://www.shirtinator.de/cT=search/mo ... enabschied aufruft bekommt man verschiedene T-Shirt Motive gelistet und hat im oberen Bereich der Seite die Möglichkeit zu wählen ob auf der Seite 50 oder 100 Motive angezeigt werden sollen, bzw. die Möglichkeit zwischen den verschiedenen Ergebnisseiten zu wechseln.

Der "Seitenwechsel" bzw. ob 50 oder 100 Motive dargestellt werden, wird über einen POST XHR Request bzw. AJAX realisiert.

Mein Ziel ist es nun ein Skript zu generieren, was mittels request libary den post requset sende, sodass ich beispielsweise den html code für 100 motive zurück bekomme.

Die form paramter sind über chrome developer tools ermittelt worden.

Aktuell sieht mein Skript wie folgt aus:

Code: Alles auswählen

import requests
import json

url = "https://www.shirtinator.de/?cT=search/motives&sq=junggesellenabschied"

data1={"xajax":"searchBrowse","xajaxr":"1455134430801","xajaxargs[]":"1","xajaxargs[]":"true","xajaxargs[]":"true",
"xajaxargs[]":"motives","xajaxargs[]":"100"}

r = requests.post(url, data=data1)
result = r.text
print result
Das Skript lifert auch die ersten paar Zeilen XML zurück, so wie unter chrome --> developer tools --> response angeziegt wird, allerdings fehlt Haupteil. Sprich es wird nicht der HTML , repsektive XML code zurück gegeben welcher die 100 Motive enthält.

Gibt es Ideen wo das Problem liegen könnte ?

Danke u Gruß
BlackJack

@bob1704: Wenn man das Wörterbuch mal so formatiert, das man es auch lesen kann, fällt das Problem sofort auf:

Code: Alles auswählen

    data = {
        'xajax': 'searchBrowse',
        'xajaxr': '1455134430801',
        'xajaxargs[]': '1',
        'xajaxargs[]': 'true',
        'xajaxargs[]': 'true',
        'xajaxargs[]': 'motives',
        'xajaxargs[]': '100',
    }
Du hast das fünf mal den gleichen Schlüssel. Davon wird nur einer übrig bleiben.

Code: Alles auswählen

#!/usr/bin/env python
# coding: utf8
from __future__ import absolute_import, division, print_function
import requests


def main():
    url = 'https://www.shirtinator.de/'
    params = {'cT': 'search/motives', 'sq': 'junggesellenabschied'}
    data = {
        'xajax': 'searchBrowse',
        'xajaxr': '1455134430801',
        'xajaxargs[]': ['1', 'true', 'true', 'motives', '100'],
    }
    response = requests.post(url, params=params, data=data)
    print(response.content)


if __name__ == '__main__':
    main()
bob1704
User
Beiträge: 27
Registriert: Dienstag 5. März 2013, 21:28

Hi BlackJack,
danke für die AW. Funzt jetz soweit.

Hast du zufällig auch eine Idee für was genau der Param

Code: Alles auswählen

'xajaxr': '1455134430801'
zuständig ist.

Gruß
BlackJack

@bob1704: Wofür das Argument genau zuständig ist weiss ich nicht, aber man kann ja relativ einfach nachlesen wie es gebildet wird und das auch in Python nachbauen. Der Link auf der Seite sieht so aus:

Code: Alles auswählen

<a href="javascript: searchBrowse('1',true,true,'motives',100)">100</a>
Wenn man nach `searchBrowse` sucht, findet man als die zwei ersten Treffer:

Code: Alles auswählen

function xajax_searchBrowse(){return xajax.call("searchBrowse",{parameters:arguments});}
und

Code: Alles auswählen

function searchBrowse(page,show_tile,show_paging,destination,page_items){xajax_searchBrowse(page,show_tile,show_paging,destination,page_items);}
Nach `call` zu suchen würde wahrscheinlich sehr viele Treffer liefern, aber wenn man mal anschaut wie die JavaScript-Dateien heissen, gibt es eine `xajax.js` und da findet man dann recht schnell die passende `call()`-Funktion, und in der wird `xajaxr` wie folgt berechnet:

Code: Alles auswählen

postData += '&xajaxr=' + new Date().getTime();
bob1704
User
Beiträge: 27
Registriert: Dienstag 5. März 2013, 21:28

Hi Black Jack,
danke vielmals für die Unterstützung.

Habe probiert das ganze jetzt nochmal probiert mit urllib und urllib2 umzusetzten.
Allerdings gibt es da wieder nur ein "Schnipsel" xml zurück.

Weiß vllt einer noch das Problem? Brauch urllib2.Request vllt zusätzlich noch header infos`?

Danke im Voraus. :))

Code: Alles auswählen

import urllib2
import urllib
#
url = "https://www.shirtinator.de/?cT=search/motives&sq=junggesellenabschied"
data = ({
        'xajax': 'searchBrowse',
        'xajaxr': '1455134430801',
        'xajaxargs[]': ['1', 'true', 'true', 'motives', '100'],
        })
encode_data = urllib.urlencode(data)
print encode_data
req = urllib2.Request(url,encode_data)
response = urllib2.urlopen(req)
d = response.read()
print d
print d.count("motiveImageBox")
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Code: Alles auswählen

In [5]: data = ({                                
        'xajax': 'searchBrowse',
        'xajaxr': '1455134430801',
        'xajaxargs[]': ['1', 'true', 'true', 'motives', '100'],
        })

In [6]: urllib.urlencode(data)
Out[6]: 'xajax=searchBrowse&xajaxargs%5B%5D=%5B%271%27%2C+%27true%27%2C+%27true%27%2C+%27motives%27%2C+%27100%27%5D&xajaxr=1455134430801'

In [7]: urllib.unquote(_)
Out[7]: "xajax=searchBrowse&xajaxargs[]=['1',+'true',+'true',+'motives',+'100']&xajaxr=1455134430801"

In [8]: urllib.urlencode(data, True)
Out[8]: 'xajax=searchBrowse&xajaxargs%5B%5D=1&xajaxargs%5B%5D=true&xajaxargs%5B%5D=true&xajaxargs%5B%5D=motives&xajaxargs%5B%5D=100&xajaxr=1455134430801'

In [9]: urllib.unquote(_)
Out[9]: 'xajax=searchBrowse&xajaxargs[]=1&xajaxargs[]=true&xajaxargs[]=true&xajaxargs[]=motives&xajaxargs[]=100&xajaxr=1455134430801'
Einfach bei `requests` bleiben, macht dir nicht nur das Leben durch eine bessere API leichter, sondern funktioniert auch auf Python 2 und 3 gleichzeitig. Spätestens ab dem Moment wo du Sessions und Cookies brauchst bereust du es sowieso nicht requests zu benutzen.
the more they change the more they stay the same
bob1704
User
Beiträge: 27
Registriert: Dienstag 5. März 2013, 21:28

OK danke.. :)

Sieht mit urllib ja schon aufwendiger aus das Ganze.

Hintergrunde warum ich es nochmal mit Urllib probiert habe war, dass die Requests libary standartmäßig nich in der Google App Engine eingebunden ist bzw offiziell nicht unterstützt wird. http://docs.python-requests.org/en/master/dev/todo/

Gruß Bob1704
Antworten