HTMLParser - Verständnisshilfe

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.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Abend Leute! :)

Ich möchte zu meinem bereits vorhandenen Programm einen Updater hinzufügen.
Dieser soll auf meine Seite "skymodz.yooco.de" (eine explizite Seite müsste ich erst noch erstellen) gehen (also öffnen und lesen) und an Hand eines Textes vergleichen, ob die Skriptversion auf meiner Seite neuer/aktueller ist als die in dem Programm.
Der Text könnte zum Beispiel so lauten: "Fortnite GamePack V1.5" - das Programm hat bspw. schon V1.5 , ließt es aber am nächsten Programmstart V1.6 (also wenn die Zahl auf der Webseite größer ist, als die auf dem Programm) so soll es den Text/Skript der neueren Version speichern.

Ich habe mich da bereits belesen.
Da habe ich diesen "HTMLParser" gefunden, doch zu seinen Funktionen "handle_data" &co. konnte ich leider nicht viel finden (weder auf deutschen, noch auf englischen Seiten).

Das ist mein aktueller Code, der die Seite nur liest - in String umwandelt und in der Shell anzeigt (so als Test obs auch funzt):

Code: Alles auswählen

import urllib.request
from html.parser import HTMLParser

Webseite = "https://skymodz.yooco.de/fortnite_gamepack"

class htmlParser(HTMLParser):
    #nothing...
    def handle_data(self,data):
        print("Test: ", data)

parser = htmlParser()
html_page = urllib.request.urlopen(Webseite)
html2string = str(html_page.read())
parser.feed(html2string)

#print(html2string)
Kann mir allerdings jemand die Funktionen genauer erklären?
Oder würdet ihr mir ein anderes Modul empfehlen?

EDIT:
Habe den Code leicht geändert, nun gibt er mir alle Texte oder so von der Seite an - aber wie filter ich den einen heraus, den ich möchte?
Z.B. "V1.5"


ps. ich hoffe es war diesmal inhaltsreicher oder so - da einer glaube meinte, ich schreibe -sinngemäß- inhaltsleer. ^^

Grüße,
xXSkyWalkerXx1
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

das ist doch unnötig kompliziert?! Leg' auf deinem Server einfach eine Route an, die bei einem Request (GET oder POST, mit oder ohne auth - wie du willst) einfach die aktuelle Skript-Versionsnummer als JSON oder plain-text oder so was zurück liefert. Dann sparst du dir das Parsen von irgendwelche HTML-Seiten.

Gruß, noisefloor
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Hey noisefloor,

Mag zwar sein, aber um Änderungen im HTML-Code von der Seite durchzuführen, müsste ich mir irgendsoein Paket kaufen. :D
Und das möchte ich momentan nicht... :')

Grüße,
xXSkyWalkerXx1
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

also hast du keine komplette über den Server, weil es nicht "dein" Server ist, richtig?

Zum Parsen von HTML-Seiten wäre IMHO das lxml die bessere Wahl, weil flexibler, bessere API usw. Wird auch hier im Forum von diversen Leuten für diverse Anwendungsfälle gerne empfohlen.

Plan B: die legst die aktuelle Versionsnummer auf einem Server ab, wo du mehr Möglichkeiten hast. Z.B. eine einfache Route bei AWS Lambda, wo die Version als JSON zurück geliefert wird.

Gruß, noisefloor
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Hey noisefloor,

Aber wie würde das auf der Weise funktionieren, die ich möchte?

Grüße,
xXSkyWalkerXx1
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Okey, habe herausgefunden, dass ich es teils mit "xpath" machen kann, der lauten würde: //*[@id="box_7195052"]/div[1]/div[2]/div/p[2]/span[1]/span/strong/span
Doch ich habe kein Plan und finde nichts was mir sagen könnte, wie ich den html.parser dazu bringe den Text auszulesen und so...

Es ist vllt einfach zu spät und müde bin ich auch ziemlich... :shock:
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Du brauchst requests und BeautifulSoup, damit geht es dann zügig...

Auf der Seite arbeitest du kaum mit HTML-Tags, was dich die Arbeit dann weniger zügig erledigen lässt. Du solltest da für die Versionsangabe eine h2 (oder so etwas) und eine id vergeben...
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Was heißt "h2" - Header2?
Wie vergebe ich denn sowas?
Benutzeravatar
noisefloor
User
Beiträge: 3854
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@xXSkyWalkerXx1: wie willst du denn erfolgreich HTML parsen, wenn dir noch nicht mal die grundlegenden Tags in HTML geläufig sind? Das ist Grundvoraussetzung, weil du sonst dem HTML-Parser nicht mitteilen kannst, wonach er überhaupt suchen soll.

Gruß, noisefloor
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Bei Dir steht das im Quelltext:

<span style="font-size: xx-large; font-family: arial, helvetica, sans-serif; color: #000000;">FORTNITE GAMEPACK V1.5</span>

Du arbeitest also nicht mit CSS3-Klassen usw. Wenn du mal Deinen Usernamen hier im Forum markierst und dann mit der rechten Maustaste anklickst, sollte im Kontextmenü so etwas wie "Element untersuchen" stehen. Wenn Du darauf klickst, dann siehst Du folgendes:

<a href="./memberlist.php?mode=viewprofile&amp;u=20401" class="username">xXSkyWalkerXx1</a>

Da ist ein Link mit der Klasse username, d. h. ich kann bs4 sagen, dass er mir alle Links (a-Tags) mit der Klasse "username" auswerfen soll. Das kann man gut parsen. Bei deinem Quelltext kann man das auch parsen, aber das ist dann mehr Glückssache. Du könntest mal ein einfaches HTML5- und CSS3-Tutorial durcharbeiten. Das könnte helfen.

Ich weiß nicht, ob Du auf deiner Seite (die dann wohl Yooco.de Social Networking System nutzt) IDs und Klassen im HTML-Quelltext vergeben kannst. Eigentlich dürfte es da etwas wie einen visuellen Editor für die Seite geben und eigentlich solltest Du dort auch Absätzen oder Textauszügen so etwas wie Vorlagen zuweisen können.
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Schau ggf. mal hier: https://www.peterkropff.de/site/html/html.htm

Das HTML- und CSS3-Tutorial kenne ich nicht, das Tutorial zu Objektorientierter Programmierung habe ich dort auf der Seite mal sehr gut gefunden. Da kann man immer anderer Meinung sein, aber beide Tutorials dürften kurz sein und ein Grundverständnis vermitteln.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Danke pixewakb!

Hab mir mal die Seite durchgelesen und es hat mein Verständnis für HTML gebessert. :)
Verstehe jetzt das mit <span> , den Klassen , etc. .

Werde nun schauen, wie man das mit BS4 schreiben kann.

Grüße,
xXSkyWalkerXx1
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Irgendwie gibt er mir nun hier "None" raus... :(

Code: Alles auswählen

from bs4 import BeautifulSoup
import urllib.request as urllib2

webseite = "https://www.dropbox.com/s/kt3d2jn4sy2llew/test.txt?dl=0"

content = urllib2.urlopen(webseite).read()
soup = BeautifulSoup(content, "lxml")
search = soup.find(id='code') 

print(search)
Ich verstehe nur nicht wieso und wie lasse ich den Inhalt von dieser ID ausgeben - mit ".contents"?
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

Auf der Seite ist ja auch kein Tag mit ID "code". dropbox ist wohl auch kaum eine geeignete Webseite für so einen Updateversionscheck.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Doch, wenn du den Link öffnest und mit der Maus auf das Layout gehst, wo der Text steht, und da den Quelltext anschaust wird mit angezeigt: ' id="code" '

Hier:

Code: Alles auswählen

<pre id="code" class="brush: text; plain-text">testfile</pre>
Zuletzt geändert von xXSkyWalkerXx1 am Sonntag 30. September 2018, 18:20, insgesamt 1-mal geändert.
nezzcarth
User
Beiträge: 1633
Registriert: Samstag 16. April 2011, 12:47

Was du da im Browser auf die von pixewakb gezeigte Weise sehen kannst, ist nicht der eigentliche Quelltext, sondern der DOM-Baum, den der Browser erzeugt, wenn die Seite fertig geladen ist; das schließt zum Beispiel auch das Ausführen von JavaScript, das zusätzliche Modifikationen durchführen kann, ein. Den eigentlichen Quelltext erhälst du im Firefox z.B. mit ctrl+U. Die Seite -- die du auch mit einem gewöhnlichen get-Request erhälst -- enthält nicht mal deinen Beispiel-String.

Im Übrigen finde ich es fragwürdig, was du da auf deiner Seite anbietest.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Doch, siehe hier:

Code: Alles auswählen

<pre id="code" class="brush: text; plain-text">testfile</pre>
Warum findest du es fragwürdig? :D
Benutzeravatar
pixewakb
User
Beiträge: 1411
Registriert: Sonntag 24. April 2011, 19:43

Du solltest das Modul requests installieren und nutzen, urllib.request nutzt man da eigentlich nicht mehr. Dropbox dürfte viel JavaScript nutzen, d. h. der Inhalt, den Du im Browser siehst, dürfte dort erst nach einem Nachladen erkennen. Wenn Du so etwas parsen willst, dann geht das mit requests nicht mehr, sondern du müsstest auf Selenium wechseln, was aber sehr langsam ist, weil das Modul einen Browser mitbringt und über den Browser (!) die Abfragen durchführt. Das ist sehr, sehr langsam.

Packt die Information auf eine statische Website im Netz und parse es dann von da. Es gibt sowohl kostenlose Anbieter für Python-Apps, aber auch Sachen, wo du eine einfache HTML-Seite ablegen kannst. Mehr braucht es eigentlich nicht.
nezzcarth
User
Beiträge: 1633
Registriert: Samstag 16. April 2011, 12:47

xXSkyWalkerXx1 hat geschrieben: Sonntag 30. September 2018, 18:36 Doch, siehe hier:

Code: Alles auswählen

<pre id="code" class="brush: text; plain-text">testfile</pre>
Nein. Siehe hier:

Code: Alles auswählen

curl -s -A "Mozilla/5.0 (X11; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0" "https://www.dropbox.com/s/kt3d2jn4sy2llew/test.txt?dl=0" | grep -i "testfile"
Warum findest du es fragwürdig? :D
Wenn ich das richtig verstanden habe, versuchst du Cheats zu verkaufen. Das ist mindestens fragwürdig.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

pixewakb hat geschrieben: Sonntag 30. September 2018, 18:41 Du solltest das Modul requests installieren und nutzen, urllib.request nutzt man da eigentlich nicht mehr. Dropbox dürfte viel JavaScript nutzen, d. h. der Inhalt, den Du im Browser siehst, dürfte dort erst nach einem Nachladen erkennen. Wenn Du so etwas parsen willst, dann geht das mit requests nicht mehr, sondern du müsstest auf Selenium wechseln, was aber sehr langsam ist, weil das Modul einen Browser mitbringt und über den Browser (!) die Abfragen durchführt. Das ist sehr, sehr langsam.

Packt die Information auf eine statische Website im Netz und parse es dann von da. Es gibt sowohl kostenlose Anbieter für Python-Apps, aber auch Sachen, wo du eine einfache HTML-Seite ablegen kannst. Mehr braucht es eigentlich nicht.
Wollte den Code ja eigentlich auf meiner skymodz.yooco.de Seite hochladen, aber da müsste ich den Thread mit einen Passwort sperren - somit müsste ich auch erstmal recherchieren wie Python das Passwort mitnimmt.

Wenn ich das richtig verstanden habe, versuchst du Cheats zu verkaufen. Das ist mindestens fragwürdig.
Warum ist das "mindestens" fragwürdig?
Außer versuche ich es nicht - sondern tue es erfolgreich seit ~2 Jahren.
Antworten