Seite 3 von 5

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 10:58
von egon11
Das heißt ich kann den gar nicht formatieren?

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 11:15
von Sirius3
Doch, aber der Formatstring muss unicode sein.

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 11:17
von __blackjack__
@egon11: Doch, aber Du musst halt sicherstellen das entweder Unicodezeichenketten in Unicodezeichenketten oder Bytezeichenketten in Bytezeichenketten formatiert werden. Am saubersten ist es für Text `unicode` zu nehmen.

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 11:30
von egon11
OK, es kommt aber nur 'None' als Ausgabe.

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 11:55
von Sirius3
Wo kommt nur None als Ausgabe? Du hast ein print mit einer Liste.

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 12:00
von egon11

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") + "\n\n"

liste.append(beschreibung)    
for row in tabelle.find_all("ul"):
    meintext = [d.unicode 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.encode('utf8'))

print("".join(liste))

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 12:25
von egon11
Sirius3 hat geschrieben: Sonntag 5. Januar 2020, 11:55 Wo kommt nur None als Ausgabe? Du hast ein print mit einer Liste.
Ja bei print kommt immer "None".

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 12:33
von Sirius3
Das kann nicht sein, denn eine Liste wird niemals "None" als Ausgabe geben.
Und einfach irgendwo an zufälligen Stellen `encode` einzustreuen, wird nicht zu einer nachhaltigen Lösung führen.

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 12:37
von egon11
Das encode habe ich wieder raus genommen. so sieht meine print Ausgabe aus:

Code: Alles auswählen

Pl   Verein                   Sp    G   UE    V    Tore Diff    P 

None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 
None None                   None None None None    None None None 

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 12:43
von Sirius3
Jetzt sehe ich erst, was Du gemacht hast. Du hast d.text durch d.unicode ersetzt. Wie kommst Du nur auf die Idee, dass das was sinnvolles sein könnte. Mit Raten kommst Du nicht weiter. Also entweder Du liest die Dokumentation oder befolgst das, was Dir hier empfohlen wird.

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 13:03
von snafu
Wie schon gesagt wurde: response.content liefert Bytes, aber in so einem Fall will man Unicode. Also muss man "text" statt "content" benutzen. Teilt man es außerdem zur Übersicht und Testbarkeit in Funktionen auf und zieht die konfigurierbaren Teile an den Anfang, dann kann das so aussehen:

Code: Alles auswählen

#!/usr/bin/env python3
from bs4 import BeautifulSoup
import requests

URL = "http://www.sportal.de/fussball/bundesliga/tabelle/tabelle-saison-2019-2020"

TABLE_CONFIG = {
    "Pl": "<4",
    "Verein": "<22",
    "Sp": ">4",
    "G": ">4",
    "UE": ">4",
    "V": ">4",
    "Tore": ">7",
    "Diff": ">4",
    "P": ">4",
}

def get_table_soup(url):
    response = requests.get(url)
    response.raise_for_status()
    soup = BeautifulSoup(response.text, "lxml")
    return soup.find(class_="table_content")

def parse_table_rows(soup):
    for row in soup.find_all("ul"):
        yield [elem.text.strip() for elem in row.find_all("li")
               if not elem.text.isspace()]

def print_table(rows, config):
    template = " ".join(f"{{:{spec}}}" for spec in config.values())
    print(template.format(*config.keys()))
    for row in rows:
        print(template.format(*row))

def main():
    rows = parse_table_rows(get_table_soup(URL))
    print_table(rows, TABLE_CONFIG)


if __name__ == '__main__':
    main()

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 13:09
von __blackjack__
@snafu: Ob man `text` oder `content` nimmt ist eigentlich egal denn das geht ja in jedem Fall durch den HTML-Parser und danach ist es `unicode`, egal was man da rein gefüttert hat. Das war ja das Problem, das versucht wurde die `unicode`-Objekte die BeautifulSoup liefert in ein `str`-Objekt zu formatieren. Und das Problem hat Dein Code auch, wenn er denn überhaupt unter Python 2 laufen würde.

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 13:19
von Sirius3
@snafu: das ist nicht das Problem. Denn wenn BeautifulSoup ein Bytes-Objekt bekommt, dann ermittelt es das Encoding wenn möglich am meta-Tag. Außerdem geht es gerade darum, das mit Python2 zum Laufen zu bringen. Da kann man sich nicht auf die Reihenfolge von Wörterbüchern verlassen oder f-Strings benutzen.

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 13:35
von snafu
response.content führt in der cmd.exe unter Windows jedenfalls zu Darstellungsproblemen mit Umlauten. Bei response.text besteht das Problem nicht. Für Python 2.7 habe ich es jetzt nicht getestet. Die neuen Features gehen da natürlich nicht. Fragt sich dann aber eher, warum jemand noch Python 2.x nutzt und ob er kein Upgrade machen kann...

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 13:49
von __blackjack__
@snafu: *Die* Frage wurde auch schon gestellt und beantwortet: Das soll ein Plugin für Enigma2 sein, und da gibt's halt nur Python 2. Das zu ändern dürfte den Rahmen sprengen. ;-)

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 13:52
von snafu
Als ob ich hier mehr als drei Beiträge im Thread lese... :lol: ;)

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 17:54
von egon11
Ich habe mir gerade gelesen dass das Modul "lxml" schneller als bs4 arbeiten soll.
Kann man daraus etwas basteln was ich vor hab?
Wenn ja ich finde dazu kein richtiges howto im Netz, eventuell jemand einen Tipp?

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 18:25
von __deets__
lxml ist bestimmt schneller, aber der Grund dafuer ist, dass es ein wrapper um die C-Bibliotheken libxml und libxslt ist. Sind die auf deiner enigma vorhanden? Sonst ist das alles vergebliche Liebesmueh.

Und so oder so frage ich mich, warum du hier rumoptimieren willst. Es fallen ja keine Tore im Mikrosekunden-Takt. Wenn es ein paar Sekunden dauert, das zu updaten - wo liegt genau das Problem?

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 18:45
von egon11
Das Problem ist, es gab mal das "kicker" plugin. Somit konnte man aktuelle Ergebnisse etc. abrufen.
Wenn man da auf eine Seite ging dauerte es nicht lang und die wurde geladen.
Wenn ich jetzt mein Plugin öffne, dauert es knapp 7 Sekunden, bis die Seite geladen hat. Und das auf einer 1,6GHZ schnellen Box.
Es gibt aber auch Boxen mit 750 MHZ...
Deswegen frage ich nach einer schnelleren alternative.

Re: Html Seite einlesen

Verfasst: Sonntag 5. Januar 2020, 19:08
von __blackjack__
@egon11: Das ist erst einmal keine Frage von `lxml` *oder*` BeautifulSoup, denn letzteres würde ich auf jeden Fall verwenden, und das kann `lxml` als Parser verwenden. Bei Python 2 würde ich auch dringend vom 'html.parser' aus der Standardbibliothek abraten, denn das war bei Python 2 nur bei fehlerfreiem HTML wirklich verwendbar. Das Modul ist erst in Python 3 robuster geworden.

Bevor Du irgendetwas optimierst solltest Du erst einmal schauen *wo* die Zeit verbraucht wird. Es gibt ja mindestens die drei Teilbereiche laden der Daten über das Netz, parsen des HTML, und dann das suchen und extrahieren der Werte.