Html Seite einlesen

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.
egon11
User
Beiträge: 363
Registriert: Mittwoch 14. Dezember 2016, 20:59

@__blackjack__ : OK ich schaue mal nach.

Wenn ich "BeautifulSoup(response.content, 'lxml')" nehme, gibt es da eine Doku?
Benutzeravatar
__blackjack__
User
Beiträge: 13970
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@egon11: Eine Doku wofür?
“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
egon11
User
Beiträge: 363
Registriert: Mittwoch 14. Dezember 2016, 20:59

BeautifulSoup mit "lxml"
Benutzeravatar
snafu
User
Beiträge: 6844
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

BS funktioniert immer gleich, was ja auch Sinn der Sache ist. Nur das Backend zum Parsen kann halt ausgetauscht werden, wodurch sich neben der Performance auch die Art, wie das HTML-Markup im Detail verarbeitet wird, etwas verändern kann. An der Schnittstelle auf BS-Ebene ändert sich dadurch nichts.

Bezüglich der langen Verarbeitungszeit würde ich an deiner Stelle erstmal messen, wie lange das reine Laden via requests dauert. Die Wahrscheinlichkeit ist hoch, das der Zugang zum Netz einfach recht lahm ist. Und ansonsten kann man es dadurch ja widerlegen und woanders weiter suchen.
egon11
User
Beiträge: 363
Registriert: Mittwoch 14. Dezember 2016, 20:59

Jetzt habe ich getestet, an dieser Stelle dauert es ziemlich lange:

Code: Alles auswählen

BeautifulSoup(response.content, 'html.parser')
Benutzeravatar
__blackjack__
User
Beiträge: 13970
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@egon11: Wie gesagt, an der Stelle sollte man dann "lxml" statt "html.parser" nehmen.
“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
egon11
User
Beiträge: 363
Registriert: Mittwoch 14. Dezember 2016, 20:59

__blackjack__ hat geschrieben: Dienstag 7. Januar 2020, 09:59 @egon11: Wie gesagt, an der Stelle sollte man dann "lxml" statt "html.parser" nehmen.
Da fangen schon die nächsten Probleme an.
Wenn ich es über IDLE ausführe geht es, allerdings nicht über Konsole, da wird mir

Code: Alles auswählen

Traceback (most recent call last):
  File "/home/prob.py", line 28, in <module>
    main()
  File "/home/prob.py", line 25, in main
    tabelle()
  File "/home/prob.py", line 10, in tabelle
    html = BeautifulSoup(response.content, 'lxml')
  File "/usr/lib/python2.7/site-packages/bs4/__init__.py", line 335, in __init__
    u"The markup you provided was rejected by the parser. Trying a different parser or a different encoding may help.\n\nOriginal exception(s) from parser:\n " + "\n ".join(other_exceptions)
bs4.builder.ParserRejectedMarkup: The markup you provided was rejected by the parser. Trying a different parser or a different encoding may help.

Original exception(s) from parser:
 UnicodeDecodeError: 'utf8' codec can't decode byte 0xfc in position 600: invalid start byte
 LookupError: unknown encoding: 'Windows-1252'

ausgegeben.
Sirius3
User
Beiträge: 18245
Registriert: Sonntag 21. Oktober 2012, 17:20

Ja, da stimmt etwas mit dem Encoding nicht. Und die Antwort wird auch gleich gegeben: The markup you provided was rejected by the parser. Trying a different parser or a different encoding may help. Vielleicht hilft auch schon response.text, wenn requests das richtige Encoding weiß.
egon11
User
Beiträge: 363
Registriert: Mittwoch 14. Dezember 2016, 20:59

@Sirius3: Das hat funktioniert, jetzt geht es auch auf der konsole.
Nur ich kann dieses Plugin nicht öffnen, obwohl ich `lxml` installiert habe.

Code: Alles auswählen

11:24:42.9942 {   } /usr/lib/python2.7/site-packages/twisted/python/util.py:815 untilConcludes 2020-01-07 11:24:42+0100 [-] FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml. Do you need to install a parser library?
egon11
User
Beiträge: 363
Registriert: Mittwoch 14. Dezember 2016, 20:59

Jetzt funktioniert es so wie es soll mit `lxml`.

Vielen Dank an alle.
Sirius3
User
Beiträge: 18245
Registriert: Sonntag 21. Oktober 2012, 17:20

In `/usr/lib/python2.7/` solltest Du gar nichts ablegen. Was der Fehler mit dem Ort, an dem die py-Datei liegt, ist mir schleierhaft.
egon11
User
Beiträge: 363
Registriert: Mittwoch 14. Dezember 2016, 20:59

Ich habe es wieder raus genommen. Es läuft,. Danke.
Nur ich verzweifle jetzt an einer Stelle, möchte mir die Ergebnisse anzeigen lassen, aber egal wie ich es filtere kommt nur Müll raus.

Hier mein code:

Code: Alles auswählen

#!/usr/bin/python
### -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup


def begegnung():
    url = "https://sport.sky.de/bundesliga-spielplan-ergebnisse"
    response = requests.get(url)
    html = BeautifulSoup(response.text, 'lxml')
    klasse = html.find(class_="sdc-site-fixres-wrap")
    print(klasse.text.strip())


if __name__=='__main__':
    begegnung()

Den seiten Quelltext habe ich mir schon angesehen, aber ich weiß nicht wonach ich es noch filtern soll, damit es einen Sinn ergibt.
Mit den Tabellen hat es immer super funktioniert.
nezzcarth
User
Beiträge: 1739
Registriert: Samstag 16. April 2011, 12:47

Das ist ja nun erneut eine andere Seite, wenn ich richtig mitgezählt habe mindestens die dritte. Was ist denn dein konkretes Ziel? Möchtest du alle drei Seiten auswerten, oder wechselst du, weil es bei den anderen Seiten technische Probleme gab?

Die Infos auf dieser Seite jetzt sind auch alle vorhanden und auslesbar. Sie sind nur eben etwas stärker fragmentiert in divs und spans abgelegt. Such nach bestimmten Schlüsselwörtern (zum Beispiel Vereinsnamen) und schau dir an (zum Beispiel mit ctrl+shift+c im Firefox), welches Element im Dom-Tree einer Tabellenzeile entspricht, dann wirst du fündig.
Zuletzt geändert von nezzcarth am Sonntag 12. Januar 2020, 11:49, insgesamt 1-mal geändert.
egon11
User
Beiträge: 363
Registriert: Mittwoch 14. Dezember 2016, 20:59

Die Seite habe ich dann gefunden und für Tabellen sehr gut geeignet. Die soll auch genutzt werden entgültig.
OK ich suche mal nach Dom-Tree.
egon11
User
Beiträge: 363
Registriert: Mittwoch 14. Dezember 2016, 20:59

Damit wird doch die Klassen gemeint oder? Habe es jetzt mal durchgetestet, aber entweder habe ich nur Vereine oder alles andere, ich dachte man kann es wie in der Tabelle mit einer Liste machen und anschließend verarbeiten.
Sirius3
User
Beiträge: 18245
Registriert: Sonntag 21. Oktober 2012, 17:20

Was sollten wir dazu sagen, ohne zu wissen, was Du jetzt gemacht hast?
egon11
User
Beiträge: 363
Registriert: Mittwoch 14. Dezember 2016, 20:59

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup


def begegnung():
    url = "https://sport.sky.de/bundesliga-spielplan-ergebnisse"
    response = requests.get(url)
    html = BeautifulSoup(response.text, 'lxml')
    for klasse in html.find_all(class_="sdc-site-fixres__team-name"):
        print(klasse.text)
    

if __name__=='__main__':
    begegnung()
Ziel soll ja sein das Spiel in einer Zeile anzuzeigen.
Im code (firefox strg + shift + c) sagt mir nichts mehr aus, als wenn ich den Quelltext öffne.
Sirius3
User
Beiträge: 18245
Registriert: Sonntag 21. Oktober 2012, 17:20

Eine Zeile hat die Klasse `sdc-site-fixres__match`. Und die Spalten haben die Klassen sdc-site-fixres__match-cell--hometeam, sdc-site-fixres__match-cell--score und sdc-site-fixres__match-cell--awayteam.
egon11
User
Beiträge: 363
Registriert: Mittwoch 14. Dezember 2016, 20:59

Warum ist der Ansatz falsch:

Code: Alles auswählen

def begegnung():
    url = "https://sport.sky.de/bundesliga-spielplan-ergebnisse"
    response = requests.get(url)
    html = BeautifulSoup(response.text, 'lxml')
    liste  = []
    alles = ""
    for text in html.find_all(class_="sdc-site-fixres-wrap"):
        for i in text.find_all(class_="sdc-site-fixres__header2"):
            print(i.text)
        for team in i.find_all(class_="sdc-site-fixres__match-cell sdc-site-fixres__match-cell--hometeam"):
            print(team.text)
Das script wird beim ersten schon beendet
Habe das BeautifulSoup schon 3x durchgearbeitet.
Sirius3
User
Beiträge: 18245
Registriert: Sonntag 21. Oktober 2012, 17:20

Falsch ist, dass Du ein HTML-Element `text` nennst, noch viel fälscher ist es eins `i` zu nennen. Und wieso glaubst Du, dass Deine Klassen besser wären als mein?
Antworten