Plugin zum Webseiteninhalt anzeigen

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Plugin zum Webseiteninhalt anzeigen

      Ich möchte den Inhalt einer Webseite angezeigt bekommen, dabei habe ich folgendes Plugin gebastelt:

      Python-Quellcode

      1. from Screens.Screen import Screen
      2. from Components.Label import Label
      3. from Components.ActionMap import ActionMap
      4. from Plugins.Plugin import PluginDescriptor
      5. import requests
      6. from bs4 import BeautifulSoup
      7. class kicker_screen(Screen):
      8. skin = """<screen position="0,0" size="1920,1080" >
      9. <widget name="myLabel" position="0,0" size="1920,1080" font="Regular;40"/>
      10. </screen>"""
      11. def __init__(self, session):
      12. self.session = session
      13. Screen.__init__(self, session)
      14. self["myLabel"] = Label(self.tabelle())
      15. self["myActionMap"] = ActionMap(["SetupActions"],{"cancel": self.close})
      16. print(self.tabelle())
      17. def tabelle(self):
      18. url = "http://www.sportal.de/fussball/bundesliga/tabelle/tabelle-saison-2019-2020"
      19. response = requests.get(url)
      20. html = BeautifulSoup(response.content, 'html.parser')
      21. tabelle = html.find(class_="table_content")
      22. 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"
      23. liste = []
      24. text = beschreibung
      25. liste.append(beschreibung)
      26. for row in tabelle.find_all("ul"):
      27. meintext = [d.text.strip() for d in row.find_all("li")]
      28. 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],\
      29. meintext[7],meintext[8],meintext[9]) + "\n")
      30. text = text + text_fertig
      31. return text
      Alles anzeigen
      Dabei treten 2 Probleme auf.
      Proplem 1: es dauert sehr lange bis er mit arbeiten fertig ist, geht das mit urllib2 schneller?
      Problem2: der Text der mir ausgegeben wird, wird nicht wie man bei print sehen kann, formatiert ausgegeben.
    • Ich habe jetzt nochmal alles gecheckt, es scheint wohl an der Schriftart zu liegen, denn das "i" ist schmäler als ein "m".
      Gibt es eine Schriftart, wo die Buchstaben alle den gleichen Platz einnehmen?
      Weil wie gesagt, die Ausgabe mit "print" ist zu 100% korrekt.
      Könnte das jemand testen?
    • Das ist doch in jedem Web-Browser auch so... die Standard-Fonts zur Anzeige von Texten haben variable Zeichenbreite. Auch im Browser sehen Tabellen dann nicht gerade aus.

      Was Du suchst ist ein Mono-Space-Font wie „Courier“. Ob die Box einen installiert hat und wie Du den dann in deinem Programm verwenden kannst, kann ich dir aber. Ich sagen

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von RickX ()

    • Vielen Dank, hat mir geholfen.
      Ich habe jetzt nach "Mono-Space-Font" gesucht und mit "Console" das passende gefunden.
      Jetzt wäre noch ein tipp wie ich die Webseite am schnellsten aufrufe. Mit "request" dauert es ziemlich lange
    • self.session.open(ScreenName)

      oder wenn der alte Screen dabei geschlossen werden soll:
      self.session.openWithCallback(self.close, ScreenName)

      edit: das es so lange dauert liegt eher an der BeautifulSoup.. diese Modul spart eher Entwicklerzeit.. keine Resourcenzeit. Schneller würde es gehen den response-Text mit regex auszulesen.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Schnickalot ()

    • PS: nimm direkt ein ScrollLabel. Mit einem Label kannst Du nicht scrollen, falls mal mehr Text dazustellen ist.

      Quellcode

      1. from Components.ScrollLabel import ScrollLabel
      2. self["myLabel"] = ScrollLabel(self.tabelle())


      Brauchst dann noch die beiden Scrolltasten (ActionMap anpassen + 2 Methoden ansprechen):

      Quellcode

      1. self["myActionMap"] = ActionMap(["SetupActions"],{"cancel": self.close, "left": self.page_up, "right": self.page_down})


      Quellcode

      1. def page_up(self):
      2. self["myLabel"].page_up()
      3. def page_down(self):
      4. self["myLabel"].page_down()
      Plus: gewöhn dir gleich bei Python die richtige Schreibweise an:
      Attribute und Methoden: alles klein mit Unterstrichen (zB self["my_label"] anstatt self["myLabel"]
      Klassennamen: Gross und gross weiter OHNE Unterstriche (zB: class KickerScreen(Screen) statt class kicker_screen(Screen))
    • Mit BeautifulSoup hab ich es mit mittels "lxml" gelöst. Das geht schneller.

      Ich habe jetzt in meinen "Hauptscreen" eine Funktion erstellt und aufgerufen mit "self["myActionMap"] = ActionMap(["SetupActions"],{"cancel":self.close,"ok":self.main})"

      Quellcode

      1. def main(self, **kwargs):
      2. self.session.open(screenTwo)
      so das aus den 1. Srceen heraus der 2. aufgerufen wird, leider wir anschließend nichts mehr angezeigt und ich kann nur noch rebooten.

      Muss da zusätzlich noch etwas eingetragen werden?
      In jeden Screen wir der Skin=xxx definiert.
    • Satfan444 schrieb:

      Quellcode

      1. def main(self, **kwargs):
      2. self.session.open(screenTwo)
      Muss da zusätzlich noch etwas eingetragen werden?
      Du musst self.session als zweiten Parameter an den zweiten Screen weitergeben und im zweiten Screen noch einmal den Skin definieren.

      self.session.open(screenTwo,self.session)

      In screenTwo die __ini__ um den Parameter „session“ erweitern.
      Damit kannst dann in screenTwo wieder self.session benutzen

      EDIT
      Musst im zweiten Screen neben dem Skin noch ActionMap definieren oder in der "def __init__" der zweiten Klasse ist ein Fehler, den du abgefangen hast und dann ist ActionMap nicht wirksam
      Rechtschreibfehler sind beabsichtigt, sie fördern ein genaueres Lesen
      Debug Log aktivieren Putty Telnet Screenshots erstellen

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von hajeku123 ()

    • So ich habe es jetzt hinbekommen, hier ist mein simples Beispiel, allerdings ohne "self.session" in "self.session.open(...)" denn da stürzt die Box ab.

      Python-Quellcode

      1. from Screens.Screen import Screen
      2. from Components.Label import Label
      3. from Components.ActionMap import ActionMap
      4. from Plugins.Plugin import PluginDescriptor
      5. class screenOne(Screen):
      6. skin = """<screen position="0,0" size="1920,1080" >
      7. <widget name="text" position="0,0" size="1920,1080" font="Console;30" valign="bottom" halign="center" backgroundColor="blue" zPosition="1" />
      8. </screen>"""
      9. def __init__(self, session):
      10. self.session = session
      11. Screen.__init__(self, session)
      12. self["text"] = Label("druecke ok")
      13. self["myActionMap"] = ActionMap(["SetupActions"],{"cancel":self.close,"ok":self.main})
      14. def main(self, **kwargs):
      15. self.session.open(screenTwo)
      16. class screenTwo(Screen):
      17. skin = """<screen position="0,0" size="1920,1080" >
      18. <widget name="two" position="0,0" size="1920,1080" font="Console;30" halign="center" backgroundColor="red" />
      19. </screen>"""
      20. def __init__(self, session):
      21. self.session = session
      22. Screen.__init__(self, session)
      23. self["two"] = Label("screen zwei")
      24. self["myActionMap"] = ActionMap(["SetupActions"],{"cancel":self.close})
      Alles anzeigen
      Jetzt die Frage an euch Experten, ob mehrere Klassen in ein Script die saubere Lösung ist?
      Oder gibt es noch eine (nicht so schwere Lösung) wie man von einen Screen zum anderen kommt.
      Nehmen wir an ich wähle etwas aus und dafür muss ein neuer Screen angezeigt werden.
    • Wenn die Box abstürzt, schau im Debug Log oder im Crashlog nach warum die Abstürzt. Ist nicht normal.

      Aus dem Bauch heraus würde ich denken, da fehlt die Deklaration von self.session in der def __init__ auf welche du dann später versuchst zuzugreifen.

      Ob du die Klassen aufteilst oder in einem Script lässt ist Geschmacksache.
      Kommt darauf an, wieviel Zeilen Code deine Klasse hat. Ist auf jeden Fall übersichtlicher und du findest einen Fehler schneller bei Aufteilung.
      Rechtschreibfehler sind beabsichtigt, sie fördern ein genaueres Lesen
      Debug Log aktivieren Putty Telnet Screenshots erstellen
    • ist schon der richtige Ansatz. Solange es übersichtlich bleibt ist alles gut.

      self.session übergibt man auch nicht bei Screens.. hat ja hajeku auch durchgestrichen. **kwargs kannste dir sparen.. übergibst ja nix.. bzw wird kwargs ja dann auch nirgends verwendet und stirbt direkt wieder. Falls Du mal wirklich was übergeben willst, einfach hinten dran klatschen ala self.session.open(ScreenName, param1, param2).. diese Übergaben müssen dann auch auf dem 2.Screen in der __init__ stehen: def __init__(self, session, param1, param2). Übergibst Du die params danach noch wie die session in Instanzattribute (self.session = session / self.param1 = param2 / self.param2 = param2) kannst Du diese dann auch in Methoden des 2.Screens weiterverwenden. Wirst du alles brauchen wenn Du durch den kicker "browsed". Wirst Dich ja von Link zu Link hangeln. Typisch ist zB die Übergabe des ausgewählten Eintrages einer Liste wie Rubriken oder so.

      Mal ein Beispiel:

      Python-Quellcode

      1. class Screen1(Screen):
      2. Skin = DEIN_SKIN
      3. def __init__(self, session):
      4. self.session = session
      5. Screen.__init__(self, session)
      6. self["header"] = Label("genres")
      7. self["list"] = List([])
      8. self["my_actions"] = ActionMap(["SetupActions"], {"ok": self.key_ok}, -1)
      9. self.load_data()
      10. def load_data(self):
      11. soup = BeautifulSoup("https://www.kicker.de", "lxml")
      12. genres = [(
      13. str(tag.a["title"]), #Titel
      14. "{}{}".format("https://www.kicker.de/", str(tag.a["href"])), #Link
      15. ) for tag in soup.find('ul', class_="kick__navbar-sports kick__js-navbar-size-check").find_all('li')]
      16. self["list"].setList(genres)
      17. def key_ok(self):
      18. genre = self["list"].getCurrent()
      19. self.session.open(Screen2, genre)
      20. class Screen2(Screen):
      21. Skin = DEIN SKIN
      22. def __init__(self, session, genre):
      23. self.session = session
      24. self.genre = genre
      25. Screen.__init__(self, session)
      26. self["header"] = Label("Sub-Genres")
      27. self["sub_header"] = Label(self.genre[0])
      28. self["list"] = List([])
      29. self["my_actions"] = ActionMap(["SetupActions"], {"ok": self.key_ok}, -1)
      30. self.load_data()
      31. def load_data(self):
      32. soup = BeautifulSoup(self.genre[1], 'lxml')
      33. sub_genres = [(
      34. str(tag.a.string).replace('\n', ''),
      35. str((tag.a["href"]),
      36. ) for tag in soup.find('ul class="kick__navbar-sub kick__js-navbar-size-check").find_all('li')]
      37. self["list"].setList(sub_genres)
      38. def key_ok(self):
      39. sub_genre = self["list"].getCurrent()
      40. self.session.open(Screen3, sub_genre)
      41. usw...
      Alles anzeigen
    • Hallo Satfan444,

      wie ich hier sehe baust du dir grade ein "Bundesliga - Ticker" der die Tabelle darstellt und evtl. noch mehr.
      Und genau sowas suche ich, bist du bereit dein plugin zu sharen? Ich bin leider noch nicht so fit mir sowas selber zu schrieben.


      Danke.
      PiT :whistling: