beautifulsoup redirect?!

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
Benutzeravatar
paitn
User
Beiträge: 15
Registriert: Montag 4. Juni 2018, 09:32

Hallo,

beim Versuch eine Webseite zu scrapen bekomme ich eine redirect Fehlermeldung (Ausschnitt):

Code: Alles auswählen

  File "/usr/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/requests/adapters.py", line 532, in send
    raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='www.ganzandereseite.de', port=443): Read timed out. (read timeout=4)
Mein Code:

Code: Alles auswählen

from bs4 import BeautifulSoup
import requests

class checker:

    def __init__(self):
        url = "https://www.eineseeite.de/mit/unterdingsies/505358"
        r = requests.get(url, allow_redirects=False, timeout=4)
        soup = BeautifulSoup(r.content, 'html5lib')
        print(soup.prettify())


start = checker()
BS4 leitet mich auf eine ganzandereseite um!
allow_redirect=False scheint keine Auswirkung zu haben.

Grüße,
Michael
Benutzeravatar
__blackjack__
User
Beiträge: 13126
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@paitn: Das hat nichts mit BeautifulSoup zu tun, die Webseite wird mit `requests` abgefragt. Bis zum erstellen des `BeautifulSoup`-Objekts kommt der Code ja gar nicht.

Der Code ist so ja nicht lauffähig, und bei mir funktioniert das Beispiel aus der Dokumentation für `allow_redirects`, also kann ich das Problem nicht nachvollziehen. Das Beispiel zeigt die Umleitung von einer HTTP auf eine HTTPS Seite:

Code: Alles auswählen

In [724]: r = requests.get("http://github.com")

In [725]: r.url
Out[725]: 'https://github.com/'

In [726]: r.history
Out[726]: [<Response [301]>]

In [727]: r.status_code
Out[727]: 200

In [728]: r = requests.get("http://github.com", allow_redirects=False)

In [729]: r.url
Out[729]: 'http://github.com/'

In [730]: r.history
Out[730]: []

In [731]: r.status_code
Out[731]: 301
In einem interaktiven Beispiel ist `r` als Name okay, aber in permanenten Quelltext sollte man das dann `response` nennen und nicht nur `r`.

`checker` sollte übrigens `Checker` geschrieben werden, weil Klassen per Konvention in „PascalCase“ benannt werden. Und `start` ist kein guter Name für ein Exemplar von `Checker`.

Die Klasse ist so auch gar keine Klasse sondern eine als Klasse verkleidete Funktion.

Sollte das mit mehr Code tatsächlich eine echte Klasse sein, würde ich so aufwändige Sachen wie Webseiten abfragen nicht in der `__init__()` machen, denn dann ist das schwer(er) den Code zu testen, weil man auch zu Testzwecken dann einen Server braucht um ein Objekt zu erstellen, oder entsprechende „mocks“ schreiben muss.

Ich versuche die `__init__()` möglichst einfach zu halten und da ausser Attribute setzen, einfache Umwandlungen, und eventuell Validierung, nichts weiter drin zu haben. Wenn mehr Vorarbeit nötig ist, kann man das in eine Klassenmethode (`classmethod()`-Dekorator) schreiben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
paitn
User
Beiträge: 15
Registriert: Montag 4. Juni 2018, 09:32

Hallo __blackjack__,

vielen Danke für deine Tipps!
Wieder einiges gelernt.

Ich werde mal einen "Roh"-Test mit der besagten Webseite vornehmen, wie du es gemacht hast - von der Python-Shell aus.

Noch als Anmerkung: ich will die Ticket-Seite eines Fußballvereins auf Änderungen abfragen. Diese leitet mich dann auf www.ticket-onlineshot.com weiter.
Benutzeravatar
paitn
User
Beiträge: 15
Registriert: Montag 4. Juni 2018, 09:32

Moment! Ich habe den Sachverhalt falsch dargestellt! Sorry!
Tatsächlich wird schon auf der Vereinsseite eine Unterseite von ticket-onlinehop ausgegeben, mit der ich den Request versuche.
Wenn ich mit dieser URL in der Python-Shell einen Request ausführe, passiert überhaupt nichts - mit oder ohne allow_requests=False. Der Befehl bleibt bei der Verarbeitung stecken und muß mit STRG+C abgebrochen werden.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Meinst du mit Unterseite einen iframe? Da kann ich mir gut vorstellen, dass die mit irgendwelchen Session/Nonce-Keys dafuer sorgen, dass die Seite nur vom Partner aus aufgerufen werden kann. Das kann man *vielleicht* nachbauen, aber im Zweifel ist Selenium da der einfachere Weg. Und natuerlich soll das wahrscheinlich genau das verhindern, was du probierst - scalping. Selbst wenn du da lautere Absichten hast, muss man halt gegen die "ich will alle Tickets & verkloppe die dann mit %50 Markup"-Leute vorgehen. Enshittification is everywhere...
Benutzeravatar
paitn
User
Beiträge: 15
Registriert: Montag 4. Juni 2018, 09:32

@__deets__
Ja, sowas habe ich schon befürchtet, daß die irgendwelche Sicherheitsmechanismen eingebaut haben.
Was ist Selenium genau?
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das haette eine Google-Anfrage doch beantwortet, oder? "python selenium", und los geht's.
Antworten