Etwas auswählen und anklicken

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.
enteenteente
User
Beiträge: 13
Registriert: Samstag 28. Januar 2012, 17:07

@Hyperion: Ja, ich hab mir auch vorgenommen das noch zu lernen :)
Super danke :)

@Blackjack: Ich hab auch gar nicht gesagt, dass ich mit Java Datenstrukturen gemacht habe 8)
Ich weiß grundsätzlich wie so Datenbankstrukturen aussehen. Aber Datenstrukturen und so hab ich noch nie gemacht.
Aber wie gesagt: Das kommt auf meine 'noch zu erledigen'-Liste ;)
Na ja...aber im weitesten Sinne sind es ja Befehle, weil ich ja meinen Programm befehle etwas zu tun, oder?

@Hyperion und Blackjack:
Vielen Dank, mehr wollte ich doch gar nicht :) Jetzt weiß ich ja wie ich das machen muss.
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

enteenteente hat geschrieben:@Blackjack: Ich hab auch gar nicht gesagt, dass ich mit Java Datenstrukturen gemacht habe 8)
Du hast also nie (assoziative) Arrays, bzw. Collections genutzt? Das schränkt aber schon die Effizienz von Java stark ein.
enteenteente hat geschrieben:Na ja...aber im weitesten Sinne sind es ja Befehle, weil ich ja meinen Programm befehle etwas zu tun, oder?
Gewöhn dich dran alles ein wenig genauer zu bezeichnen, das wird dir sehr helfen wenn du dich mit anderen austauschen willst :mrgreen:
enteenteente
User
Beiträge: 13
Registriert: Samstag 28. Januar 2012, 17:07

@webspider:

Ähm...
nö.
Aber das Wort klingt schön :D
Okay mache ich, dann versteht man mich auch :wink:
enteenteente
User
Beiträge: 13
Registriert: Samstag 28. Januar 2012, 17:07

Okay, noch ne Frage:

Ich habe jetzt überlegt, dass es vielleicht einfacher ist, statt die Seite zu parsen einfach mit string in der Zeichenkette nach dieser Nummer zu gucken. Es ist eine relativ lange Zeichenkette, kann ich das dann mit longstringitem machen? Und geht das überhaupt? Wenn ja, weiß jemand mit was für nem Code man das in Python3.2 macht?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

enteenteente hat geschrieben: Ich habe jetzt überlegt, dass es vielleicht einfacher ist, statt die Seite zu parsen einfach mit string in der Zeichenkette nach dieser Nummer zu gucken.
Es wurden Dir doch schon HTML-Parser-Module empfohlen - schau Dir die doch mal an! Am einfachsten kommst Du vermutlich über CSS-Selektoren da ran.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
needsch
User
Beiträge: 15
Registriert: Donnerstag 22. Dezember 2011, 21:28

@BlackJack:
HTTP ist das einzige Protokoll, dessen Grundprinzip er hier kennen sollte. Die Einarbeitung in "Netzwerk-Protokolle" vorzuschlagen oder zu fordern ist IMO etwas überzogen. Die unteren Schichten des TCP/IP-Modells braucht er erstmal sowieso nicht zu kennen.

@ente:
Wenn die Nummer, nach der du suchst, in einem HTML-Code eingebettet ist, der nicht überall auf der Seite ständig auftaucht, dann wäre ein regulärer Ausdruck das einfachste:
"In computing, a regular expression provides a concise and flexible means for "matching" (specifying and recognizing) strings of text, such as particular characters, words, or patterns of characters."

Man kann reguläre Ausdrücke also dafür nutzen, bestimmte Muster in Strings (auch Byte-Strings) zu finden. In Python kann dafür das re-Modul genutzt werden.

Primitives Beispiel:

Code: Alles auswählen

import re

strings = ["Hallo ente!", "Tschüß ente!", "bla bla ...guten MoRgEn bruder... bla bla"]

# Das angegebene pattern passt auf alle Kombinationen von "hallo", "guten tag", "guten morgen",
# "guten abend" und einem beliebigen Wort, das nur aus Buchstaben besteht.
pattern = r"(?:hallo|guten tag|guten morgen|guten abend) [a-zA-Z]+"

for string in strings:
    match_obj = re.search(pattern, string, re.I) # re.I <-> case-insensitive

    if match_obj:
        print("Der string '%s' enthält eine Begrüßung!" % string)
    else:
        print("Der string '%s' enthält keine bekannte Begrüßung!" % string)
Ausgabe:

Code: Alles auswählen

Der string 'Hallo ente!' enthält eine Begrüßung!
Der string 'Tschüß ente!' enthält keine bekannte Begrüßung!
Der string 'bla bla ...guten MoRgEn bruder... bla bla' enthält eine Begrüßung!
Anderes Beispiel, um ganz bestimmte Teile eines Musters zu extrahieren (hier geheime Nummern aus einem HTML-Code):

Code: Alles auswählen

import re

from pprint import pprint

html = """
<html>
<head>
<title>bla bla bla</title>
</head>

<body>
<span class='secret-number'>1337</span>
<div id='irgendein-super-dummer-html-code'>
    <span class='secret-number'>42</span>
    <span class='tja-das-wird-nicht-klappen secret-number'>73</span>
</div>
</body>
</html>
"""

# In Klammern stehendes kann vom regulären Ausdruck separat erfasst und später ausgelesen werden.
pattern = r"<span class='secret-number'>([0-9]+)</span>"

matches = re.findall(pattern, html, re.I)
pprint(matches)
Ausgabe:

Code: Alles auswählen

['1337', '42']
Die dritte secret-number wird nicht erfasst, weil das angegebene Pattern fordert, dass exakt "<span id='secret-number'>" am Anfang steht. Wenn auch nur irgendein Leerzeichen anders gesetzt ist oder andere Hochkommata benutzt werden oder, wie in diesem Fall, irgendein zusätzlicher Text drinsteckt, dann wird es nicht klappen. Reguläre Ausdrücke wissen nichts von HTML - es werden einfach nur exakte Übereinstimmungen mit dem angegebenen Muster gesucht.

Da kann man sich dann sehr komplizierte reguläre Ausdrücke ("pattern") überlegen, die all das beachten. Das ist aber relativ anspruchsvoll und erfordert häufig eine Menge Erfahrung mit regulären Ausdrücken; die Syntax ist für Anfänger erstmal relativ kompliziert. In deinem Fall reicht aber vllt. schon etwas ganz simples. (Das pattern in meinem Beispiel ist ja jetzt auch nicht so mörder-schwer, oder?)

Das wäre das erste, was ich versuchen würde. Wenn du so etwas häufiger machst, solltest du aber vielleicht doch mal einen HTML-Parser ausprobieren. Damit ist auf Dauer auch angenehmer zu arbeiten.

Viele Grüße

EDIT: id-Attribute durch class-Attribute ersetzt. Danke @BlackJack.
Zuletzt geändert von needsch am Dienstag 31. Januar 2012, 22:15, insgesamt 2-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@needsch: Musst Du den "neuen" denn gleich mit RegExps in Zusammenhang mit rekursivem Markup "verderben"? :twisted: Mal im Ernst, mit `lxml` geht das doch mindestens genaus so einfach:

Code: Alles auswählen

In [11]: import lxml.html                

In [12]: html = """                      
<html>
<head>
<title>bla bla bla</title>
</head>
<body>
<span id='secret-number'>1337</span>
<div id='irgendein-super-dummer-html-code'>
    <span id='secret-number'>42</span>
    <span id='tja-das-wird-nicht-klappen secret-number'>73</span>
</div>
</body>
</html>
"""

In [13]: doc = lxml.html.fromstring(html)

In [14]: [node.text for node in doc.xpath("//span[@id='secret-number']")]
Out[14]: ['1337', '42']
Natürlich kann man bei so einfachen Geschichten auch einen RegExp einsetzen; aber wenn man sich daran gewöhnt und nicht überblicken kann, wo die Grenzen dieser Technik liegen, dann gerät man schnell auf die "schiefe Bahn".
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

`lxml` kann übrigens auch direkt im XPath-Statement den Text rausfischen:

Code: Alles auswählen

doc.xpath("//span[@id='secret-number']/text()")
needsch
User
Beiträge: 15
Registriert: Donnerstag 22. Dezember 2011, 21:28

Hyperion hat geschrieben:@needsch: Musst Du den "neuen" denn gleich mit RegExps in Zusammenhang mit rekursivem Markup "verderben"? :twisted: Mal im Ernst, mit `lxml` geht das doch mindestens genaus so einfach:

Code: Alles auswählen

In [11]: import lxml.html                

In [12]: html = """                      
<html>
<head>
<title>bla bla bla</title>
</head>
<body>
<span id='secret-number'>1337</span>
<div id='irgendein-super-dummer-html-code'>
    <span id='secret-number'>42</span>
    <span id='tja-das-wird-nicht-klappen secret-number'>73</span>
</div>
</body>
</html>
"""

In [13]: doc = lxml.html.fromstring(html)

In [14]: [node.text for node in doc.xpath("//span[@id='secret-number']")]
Out[14]: ['1337', '42']
Stimmt, das ist deutlich schöner, danke für das Beispiel. Habe zu meinem Bedauern noch nie mit lxml oder allg. XPath gearbeitet. Ich muss das bei Gelegenheit unbedingt mal ausprobieren. Sonst Bildungslücke. :oops: Kommt auf die TODO. :)

Viele Grüße
lunar

@needsch: Wenn man mit HTTP arbeitet, muss man wissen, wie das Request-Response-Modell von HTTP funktioniert, und mithin auch, was eine TCP-Verbindung ist, wie sie zustande kommt, und wann sie wieder beendet wird. Es verlangt ja niemand, dass er die Headerdaten von TCP/IP auswendig lernt, aber eine grundlegende Vorstellung von der Funktionalität von TCP/IP ist mindestens hilfreich.
enteenteente
User
Beiträge: 13
Registriert: Samstag 28. Januar 2012, 17:07

Okay vielen Dank, ich probier einfach mal aus, was mir so am ehesten gelingt :D
Wieso eigentlich immer "er"? Ich bin kein Mann :mrgreen:
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

enteenteente hat geschrieben:Wieso eigentlich immer "er"? Ich bin kein Mann :mrgreen:
Wuff!
enteenteente
User
Beiträge: 13
Registriert: Samstag 28. Januar 2012, 17:07

Haha :mrgreen:
enteenteente
User
Beiträge: 13
Registriert: Samstag 28. Januar 2012, 17:07

Haha :)
Woher weißt du das?!
problembär

enteenteente hat geschrieben:Na das ist ja mal freundlich!
Mach' Dir nichts draus, die sind hier halt so.

Für einfache Fälle des Durchsuchens von Strings braucht man in Python nicht unbedingt RegEx einzusetzen. Das geht auch schon so:

Code: Alles auswählen

a = "Hallo"

if "lo" in a:
    print("'lo' ist in dem String 'a'.")
Einfach und schön. :P
enteenteente
User
Beiträge: 13
Registriert: Samstag 28. Januar 2012, 17:07

Gut zu wissen :)
Danke. Okay probiere ich aus :)
JonasR
User
Beiträge: 251
Registriert: Mittwoch 12. Mai 2010, 13:59

Solange man sich richtig verhält sind alle nett zu einem :) So wie man es erwartet
BlackJack

@needsch: Ergänzend zu dem Beitrag von Hyperion mit `lxml.html`: Dein HTML ist ungültig, weil `id`\s a) eindeutig sein müssen, und b) keine Leerzeichen enthalten dürfen. Was Du da gemacht hast findet man aber üblicherweise so in `class`-Attributen. Und dann kann man mit der `cssselect()`-Methode ganz einfach alle drei Zahlen filtern:

Code: Alles auswählen

In [77]: html = """
   ....: <html>
   ....: <head>
   ....: <title>bla bla bla</title>
   ....: </head>
   ....: <body>
   ....:     <span class='secret-number'>1337</span>
   ....:     <div id='irgendein-super-dummer-html-code'>
   ....:         <span class='secret-number'>42</span>
   ....:         <span class='tja-das-wird-nicht-klappen secret-number'>73</span>
   ....:     </div>
   ....: </body>
   ....: </html>
   ....: """

In [78]: doc = lxml.html.fromstring(html)

In [79]: doc.cssselect('.secret-number')
Out[79]: 
[<Element span at 93bf9ec>,
 <Element span at 93bf86c>,
 <Element span at 93bf89c>]

In [80]: [node.text for node in doc.cssselect('.secret-number')]
Out[80]: ['1337', '42', '73']
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@BlackJack: Ja, ich hatte mich auch ein wenig gewundert, dass da ein Beispiel mit ``id``s daher kam. Ich hatte zuvor ja auch eher CSS-Selektoren vorgeschlagen. Aber schön, dass Du auch diesen Ansatz gezeugt hast.

@problembär: Dein Einwand ist durchaus sinnvoll, aber nur dann, wenn man einen Teilstring kennt und wissen will, ob der in einem enthalten ist. In diesem Falle kennt die OP den String ja nicht, sondern will ihn herausfinden ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten