Seite 2 von 5
Re: Html Seite einlesen
Verfasst: Freitag 27. Dezember 2019, 21:53
von egon11
OK, habe es gerade auch gemerkt, aber wenn ich es wie @Sirius3 vorgeschlagen hat mache
Code: Alles auswählen
html = BeautifulSoup(response.content, 'html.parser')
tabelle = html.find('table')
for row in tabelle.find_all('tr'):
print([cell.text.strip() for cell in row.find_all('td')]
stehen die Vereinsnamen doppelt da.
Sonst wäre es ok.
Re: Html Seite einlesen
Verfasst: Freitag 27. Dezember 2019, 22:04
von __blackjack__
@egon11: Wenn dabei zu viel rum kommt, muss man halt etwas gezielter vorgehen als einfach aus jeder Zelle den gesamten Text zu extrahieren.
Re: Html Seite einlesen
Verfasst: Freitag 27. Dezember 2019, 22:56
von nezzcarth
egon11 hat geschrieben: ↑Freitag 27. Dezember 2019, 21:53
stehen die Vereinsnamen doppelt da.
Sonst wäre es ok.
Mein Eindruck ist, dass du vielleicht mit HTML noch nicht ganz warm geworden bist.

Wenn das der Fall sein sollte, möchte ich meinen Vorschlag von oben noch mal präzisieren: Nimm dir ein paar Stunden Zeit und lies dich ein wenig in HTML und evtl. CSS ein (BeautifulSoup unterstützt CSS-Selektoren). Gute Infos gibt es zum Beispiel beim
Mozilla Developer Network (früher war "SELFHTML" eine weitere übliche Empfehlung, aber das habe ich mir ewig nicht angesehen.) Anschließend kannst du dir mit den Funktionen deines Browsers mal den Quelltext und den Dom-Tree (strg+c in Firefox) ansehen. Aus meiner Sicht ist das jedenfalls eine Voraussetzung, um die Aufgabe, die du dir gestellt hast zu bewältigen.
Re: Html Seite einlesen
Verfasst: Samstag 28. Dezember 2019, 09:50
von egon11
Ok mache ich, schon mal vielen Dank.
Ich bin bei linkedin, da gibt es auch lern video's, kann da jemand etwas empfehlen?
Re: Html Seite einlesen
Verfasst: Sonntag 29. Dezember 2019, 11:14
von egon11
Ich habe jetzt mehrere Stunden damit verbracht, und habe jetzt mal folgendes geschrieben was genau meine Ansprüche hat.
Hier der Code:
Code: Alles auswählen
import requests
from bs4 import BeautifulSoup
url = "http://www.sportal.de/fussball/bundesliga/tabelle/tabelle-saison-2019-2020"
response = requests.get(url)
html = BeautifulSoup(response.content, 'html.parser')
tabelle = html.find(class_="table_content")
liste = []
beschreibung = "{0:<4} {1:<22} {2:>4} {3:>4} {4:>4} {5:>4} {6:>7} {7:>4} {8:>4} ".format("Pl", "Verein", "Sp", "G", "UE", "V", "Tore", "Diff", "P")
liste.append(beschreibung)
for row in tabelle.find_all("ul"):
meintext = [d.text.strip() for d in row.find_all("li")]
text_fertig = "{0:<4} {1:<22} {2:>4} {3:>4} {4:>4} {5:>4} {6:>7} {7:>4} {8:>4} ".format(meintext[0],meintext[2],meintext[3],meintext[4],meintext[5],meintext[6],\
meintext[7],meintext[8],meintext[9])
liste.append(text_fertig)
for text in liste:
print(text)
Es kann ja mal jemand drüber schauen ob das so ok ist, und was man eventuell noch verbessern/erweitern kann.
Vielen Dank
Re: Html Seite einlesen
Verfasst: Samstag 4. Januar 2020, 18:42
von egon11
Ich muss leider noch einmal fragen.
Der Code funktioniert ja recht gut in python3.
Jetzt möchte ich es mal mit urllib bzw urllib2 in python2 testen.
Wie muss der code dann aussehen?
Code: Alles auswählen
import requests
from bs4 import BeautifulSoup
url = "http://www.sportal.de/fussball/bundesliga/tabelle/tabelle-saison-2019-2020"
response = requests.get(url)
html = BeautifulSoup(response.content, 'html.parser')
Re: Html Seite einlesen
Verfasst: Samstag 4. Januar 2020, 18:48
von __deets__
Python zwei ist tot. Seit diesem Jahr.
https://pythonclock.org/
Warum also etwas damit testen?
Re: Html Seite einlesen
Verfasst: Samstag 4. Januar 2020, 18:50
von Sirius3
Warum möchtest du das? Python2 ist veraltet. Im übrigen verwendest du kein urllib, sondern request. Der Code sieht also identisch aus.
Re: Html Seite einlesen
Verfasst: Samstag 4. Januar 2020, 18:57
von egon11
Ich möchte es in enigma2 einbauen, und da läuft nur python2.
Ich habe es mit 'request' gemacht, das ganze läuft auch, ich wollte nur mal testen ob das mit 'urllib2' schneller läuft, weil 'request' ganz schön lange dauert.
Re: Html Seite einlesen
Verfasst: Samstag 4. Januar 2020, 19:20
von nezzcarth
egon11 hat geschrieben: ↑Samstag 4. Januar 2020, 18:57
Ich möchte es in enigma2 einbauen, und da läuft nur python2.
Ich habe es mit 'request' gemacht, das ganze läuft auch, ich wollte nur mal testen ob das mit 'urllib2' schneller läuft, weil 'request' ganz schön lange dauert.
Was meinst du mit "dauert ganz schön lange"? Die einzelnen Anfragen? Die Erfahrung habe ich nicht gemacht; requests ist zwar sicher nicht die schnellste HTTP-Bibliothek für Python, aber von denen, die ich kenne die, die am angenehmsten zu benutzen ist und normalerweise schnell genug. Bottlenecks sind eher außerhalb von requests zu verorten, entweder im Netzwerk (langsam antwortende Server etc.), oder im restlichen Code. Als Fallback für Fälle, in denen requests nicht genügt, verwende ich manchmal
PyCurl/libcurl. Damit kann man sich dann maßgeschneiderte, effiziente Anfragen basteln. Allerdings ist das nur ein dünner (sehr unpythonischer) Wrapper um eine C-Bibliothek, entsprechend Low-Level und unhandlich in der Benutzung. Vielleicht hat jemand anderes noch einen zugänglicheren Vorschlag.
Soweit ich jetzt auf Schnelle herausfinden konnte, haben die Entwickler von diesem 'enigma2' den Wechsel zu Python3 sehenden Auges verschlafen und auch nur so mittelmäßiges Interesse, da nachzubessen. Super :/
Re: Html Seite einlesen
Verfasst: Samstag 4. Januar 2020, 19:27
von egon11
nezzcarth hat geschrieben: ↑Samstag 4. Januar 2020, 19:20
Soweit ich jetzt auf Schnelle herausfinden konnte, haben die Entwickler von diesem 'enigma2' den Wechsel zu Python3 sehenden Auges verschlafen und auch nur so mittelmäßiges Interesse, da nachzubessen. Super :/
Ja genau so ist es.
Genau genommen dauert der Teil lange:
Code: Alles auswählen
response = requests.get(url)
html = BeautifulSoup(response.content, 'html.parser')
Gibt es für 'bs4' eine Alternative?
Ich schaue mir gerade mal 'xml.etree' an.
Re: Html Seite einlesen
Verfasst: Samstag 4. Januar 2020, 19:41
von nezzcarth
egon11 hat geschrieben: ↑Samstag 4. Januar 2020, 19:27
Genau genommen dauert der Teil lange:
Code: Alles auswählen
response = requests.get(url)
html = BeautifulSoup(response.content, 'html.parser')
Gibt es für 'bs4' eine Alternative?
Hier kann man nicht sagen, ob der HTTP-Request oder das Einlesen der Daten lange dauert. Das solltest du eingrenzen, bevor du mit Optimierungen beginnst.
BeautifulSoup greift auf eine Parser-Bibliothek zurück. Du verwendest 'html.parser' aus der Standardbibliothek. Andere Optionen sind die externen, separat zu installierenden Bibliotheken 'lxml' und 'html5lib'. 'lxml' ist nach meiner Erfahrung die schnellste Option.
Re: Html Seite einlesen
Verfasst: Samstag 4. Januar 2020, 19:52
von egon11
OK, wenn ich jetzt 'lxml' einsetze, kann er
nicht umsetzen, muss dann der ganze code geändert werden?
Re: Html Seite einlesen
Verfasst: Samstag 4. Januar 2020, 21:13
von nezzcarth
Was meinst du damit? Wenn es die Klasse "table_content" gibt, erhält man auch mit lxml als Backend die entsprechenden Elemente als Resultat.
'class'-Attribute können übrigens von mehreren Elementen verwendet werden, mit 'find' bekommst aber immer nur das erste. Für den Fall, dass es mehr als ein Resultat geben kann, gibt es 'find_all'. Wenn das Element, das du suchst, ein 'id'-Attribut hat, wäre es meiner Meinung nach sauberer das zu verwenden, da id-Attribute einmalig sein sollen.
Re: Html Seite einlesen
Verfasst: Sonntag 5. Januar 2020, 09:53
von egon11
Ich habe jetzt so
Code: Alles auswählen
import requests
from bs4 import BeautifulSoup
url = "http://www.sportal.de/fussball/bundesliga/tabelle/tabelle-saison-2019-2020"
response = requests.get(url)
html = BeautifulSoup(response.content, 'lxml-xml').encode('utf-8')
tabelle = html.find(class_="table_content")
Dann kommt der Fehler:
Code: Alles auswählen
Traceback (most recent call last):
File "/home/scrip.py", line 8, in <module>
tabelle = html.find(class_="table_content")
TypeError: find() takes no keyword arguments
Re: Html Seite einlesen
Verfasst: Sonntag 5. Januar 2020, 09:56
von nezzcarth
Nimm 'lxml' statt 'lxml-xml'.
Re: Html Seite einlesen
Verfasst: Sonntag 5. Januar 2020, 10:06
von egon11
Genau das gleiche.
Re: Html Seite einlesen
Verfasst: Sonntag 5. Januar 2020, 10:14
von nezzcarth
Achso, lass ".encode('utf-8')" weg. Das macht nicht, was du vielleicht denkst und verursacht das Problem, da es dem BeautifulSoup-Objekt 'bytes' macht. Das kann man übrigens leicht mit 'type(html)' im interaktiven Interpreter ausprobieren.
Re: Html Seite einlesen
Verfasst: Sonntag 5. Januar 2020, 10:36
von egon11
Ohne
kommt der Fehler:
Code: Alles auswählen
Traceback (most recent call last):
File "/home/scrip.py", line 16, in <module>
meintext[7],meintext[8],meintext[9]) + "\n"
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-2: ordinal not in range(128)
Mein code sieht aktuell so aus:
Code: Alles auswählen
import requests
from bs4 import BeautifulSoup
url = "http://www.sportal.de/fussball/bundesliga/tabelle/tabelle-saison-2019-2020"
response = requests.get(url)
html = BeautifulSoup(response.content, 'lxml')
tabelle = html.find(class_="table_content")
liste = []
beschreibung = "{0:<4} {1:<22} {2:>4} {3:>4} {4:>4} {5:>4} {6:>7} {7:>4} {8:>4} ".format("Pl", "Verein", "Sp", "G", "UE", "V", "Tore", "Diff", "P")
liste.append(beschreibung)
for row in tabelle.find_all("ul"):
meintext = [d.text.strip() for d in row.find_all("li")]
text_fertig = "{0:<4} {1:<22} {2:>4} {3:>4} {4:>4} {5:>4} {6:>7} {7:>4} {8:>4} ".format(meintext[0],meintext[2],meintext[3],meintext[4],meintext[5],meintext[6],\
meintext[7],meintext[8],meintext[9]) + "\n"
liste.append(text_fertig)
print(liste)
Re: Html Seite einlesen
Verfasst: Sonntag 5. Januar 2020, 10:50
von __blackjack__
@egon11: Bei Python 2 musst Du halt selbst besser zwischen Text und Bytes unterscheiden und expliziter damit sein was Du haben willst. Du versuchst hier Text (`unicode`) in Byteketten (`str`) zu formatieren. Mach aus dem Text in den Du da formatieren willst mit einem u ein `unicode`-Objekt.