String Funktionen

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.
Antworten
de_master
User
Beiträge: 72
Registriert: Samstag 15. Januar 2005, 15:19

Hallo @ all,
ich bin auf der suche nach einer List über allen String Funktionen die mir Python zur verfügung stellt.

Ich habe nun in mehreren Tutorials nachgeschaut, jedoch finde ich in jedem Tutorial nur bruchweise String funktionen. In vielen auch gar nichts darüber.

Ich möchte diesen html Text http://www.ubuntuusers.de/paste/7930/ parsen und brauche daraus jeweils folgende Informationen (class=xl36 und Texte zwischen den <>).

Mit welchen Funktionen würdet ihr diesen Text parsen?

Danke schonmal im Vorraus.

Gruss Michael
Byte
User
Beiträge: 63
Registriert: Dienstag 26. September 2006, 07:04

Hi de_master,

habe keine Ahnung ob dir das was hilft, hat die Forumsuche mit HTML auf der erste Seite hergegeben.

http://www.python-forum.de/topic-4664.html

Gruss
Christian
Benutzeravatar
Dill
User
Beiträge: 470
Registriert: Mittwoch 10. Januar 2007, 14:52
Wohnort: Köln

schau mal hier:
http://rgruet.free.fr/PQR25/PQR2.5.html

abschnitte:
Operations on mutable sequences (type list)
Operations on strings (types str & unicode)


... oder die python library reference
BlackJack

Ich würde auch BeautifulSoup empfehlen.

Hier ein Beispiel für das finden der Klassen und des ersten (Text)knotens innerhalb der ersten 15 `td`-Tags die ein `class`-Attribut haben:

Code: Alles auswählen

In [72]: [(node['class'], node.contents[0])
   ....:  for node in soup.findAll('td', {'class': True}, limit=15)]
Out[72]:
[(u'xl36', u'Stamm (Men\xfc)'),
 (u'xl58', u'4.4'),
 (u'xl64', u'-'),
 (u'xl47', u'Jasmin'),
 (u'xl40', u'Ja'),
 (u'xl50', u'-'),
 (u'xl55', u'16.10.2006'),
 (u'xl33', u'Simon'),
 (u'xl45', u'Ja'),
 (u'xl52', u'-'),
 (u'xl56', u'-'),
 (u'xl63', u' '),
 (u'xl61', u' '),
 (u'xl32', u' '),
 (u'xl32', u' ')]
de_master
User
Beiträge: 72
Registriert: Samstag 15. Januar 2005, 15:19

BlackJack hat geschrieben:Ich würde auch BeautifulSoup empfehlen.

Hier ein Beispiel für das finden der Klassen und des ersten (Text)knotens innerhalb der ersten 15 `td`-Tags die ein `class`-Attribut haben:

Code: Alles auswählen

In [72]: [(node['class'], node.contents[0])
   ....:  for node in soup.findAll('td', {'class': True}, limit=15)]
Out[72]:
[(u'xl36', u'Stamm (Men\xfc)'),
 (u'xl58', u'4.4'),
 (u'xl64', u'-'),
 (u'xl47', u'Jasmin'),
 (u'xl40', u'Ja'),
 (u'xl50', u'-'),
 (u'xl55', u'16.10.2006'),
 (u'xl33', u'Simon'),
 (u'xl45', u'Ja'),
 (u'xl52', u'-'),
 (u'xl56', u'-'),
 (u'xl63', u' '),
 (u'xl61', u' '),
 (u'xl32', u' '),
 (u'xl32', u' ')]
Danke für den Code, jedoch würdest du mir bitte den code posten mit import? Irgendwie möchte das nicht klappen :(.

Gruss Michael
BlackJack

Dem vorausgegangen ist:

Code: Alles auswählen

In [76]: from BeautifulSoup import BeautifulSoup

In [77]: soup = BeautifulSoup(source)
Wobei `source` an eine Zeichenkette mit dem Beispielquelltext aus der URL gebunden ist.
de_master
User
Beiträge: 72
Registriert: Samstag 15. Januar 2005, 15:19

Hi @ all,
so ich habe nun meine ersten Gehversuche mit BeautifulSoup gemacht.
Nun habe ich jedoch ein kleines Problem. Die Ausgabe funktioniert nur so lange bis Tags im Ergebnis vorkommen.

Hier der Code: http://www.ubuntuusers.de/paste/8127/
Wer möchte, dem kann ichs auc hier nochmal posten.

Sobald die Zeile 40 geparst wird bekomme ich folgenden Fehler:

<td height=17 class=xl71 style='height:12.75pt;border-top:none'><span style='mso-spacerun:yes'> </span>Auswahlliste Kunden (Fenster)</td>

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Dokumente und Einstellungen\Michael.Strecker\Desktop\beautifolSoup.py", line 73, in <module>
    if anker.contents[0][0] == "&":
  File "C:\Python25\lib\BeautifulSoup.py", line 438, in __getitem__
    return self._getAttrMap()[key]
KeyError: 0
Wenn ich nun aus der Zeile "<span style='mso-spacerun:yes'> </span>" entferne, dann funktioniert es. Dummerweise habe ich einige dieser zusätzlichen Tags in meiner html Datei.

Könnte mir einer bitte weiterhelfen und mir sagen wie ich diese Tags erkenne bzw. ignorieren kann?

Gruss Michael
Benutzeravatar
nkoehring
User
Beiträge: 543
Registriert: Mittwoch 7. Februar 2007, 17:37
Wohnort: naehe Halle/Saale
Kontaktdaten:

Irgendwie habe ich noch nicht verstanden, was genau du willst... einmal die classe des td-Tags ...und einmal der gesamte Inhalt, oder wie? Also alles zwischen <td> und </td>? Oder doch einfach alles?

Naja, vielleicht hilft dir jedenfalls die Methode string... hier mal ein kleines (nicht all zu professionell gehaltenes) Beispiel:

Code: Alles auswählen

>>> from BeautifulSoup import BeautifulSoup as BS
>>> soup = BS("<td class=\"x86\"><b>FLUNTSCH</b></td>")
>>> soup
<td class="x86"><b>FLUNTSCH</b></td>
>>> soup.td
<td class="x86"><b>FLUNTSCH</b></td>
>>> soup.td.b
<b>FLUNTSCH</b>
>>> soup.td.b.string
u'FLUNTSCH'
EDIT: ...und evtl kannst du auch damit was anfangen...

Code: Alles auswählen

>>> soup = BS("<td height=17 class=xl71 style='height:12.75pt;border-top:none'>\n\
... <span style='mso-spacerun:yes'> </span>Auswahlliste Kunden (Fenster)</td>")
>>> soup
<td height="17" class="xl71" style="height:12.75pt;border-top:none">
<span style="mso-spacerun:yes"> </span>Auswahlliste Kunden (Fenster)</td>
>>> soup.td.string
>>> soup.td.contents
[<span style="mso-spacerun:yes"> </span>, u'Auswahlliste Kunden (Fenster)']
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
BlackJack

Da tauchen neben Zeichenketten also auch `span`-Tags in den Inhalten auf. Hier ist eine Lösung die einfach alle Tags verwirft und nur den Text aus den `td`-Tags heraus holt:

Code: Alles auswählen

soup = BeautifulSoup(html, convertEntities=BeautifulSoup.HTML_ENTITIES)

for td_node in soup('td'):
    if td_node.has_key('height'):
        print
        class_ = td_node.get('class')
        for character in 'xl':
            if class_.startswith(character):
                class_ = class_[1:]
        print 'Gruppe:', class_
    content = ''.join(td_node(text=True))
    if content.strip():
        print 'Inhalt:', content
Und ich habe dem Parser gesagt, dass er Entities in Zeichen wandeln soll. Darum gibt es kein ' ' mehr als Text, sondern das entsprechende Zeichen. Damit muss sich die Bedingung ändern bei der der Inhalt ausgegeben wird. Alle Inhalte, die ausschliesslich aus Leerzeichen bzw. "whitespace" bestehen, werden nicht ausgegeben.
de_master
User
Beiträge: 72
Registriert: Samstag 15. Januar 2005, 15:19

Vielen Dank BlackJack. Es funktioniert :)

@nkoehring, ich brauch aus dem ersten <td> das class und die Werte die zwischen den <td> stehen. Da jedoch zwischen den <td> jeder Müll drinstehen kann muss ich die Tags Filter.

Bis zu den nächsten Fragen :).

Gruss Michael
de_master
User
Beiträge: 72
Registriert: Samstag 15. Januar 2005, 15:19

BlackJack hat geschrieben:

Code: Alles auswählen

                class_ = class_[1:]
Hallo BlackJack,
ein kleines Problem gibt es jedoch noch. Ist mir gerade erst aufgefallen.
Die Zeile "class_ = class_[1:]" gibt mir leider nicht das gewünschte Ergebnis. Es schneidet 2 Zeichen weg anstatt eines.

Ein Beispiel: Ich erhalte aus meinem Dokument den Wert "x136". Diese Zeile schneidet mir dann die ersten beiden Zeichen weg :(. Bekomme als Rückgabe nur "36" zurück.
Wenn ich [0:] setze, bekomme ich den kompletten Wert "x136".

Wo könnte das Problem liegen?

Gruss Michael
BlackJack

Das liegt nicht an der einzelnen Zeile sondern an der Schleife in der sie steht, und die setzt das um, was Du in Deinem Quelltext in Zeile 67-70 gemacht hast: Wenn die Zeichenkette mir einem 'x' beginnt, dieses entfernen und danach das gleiche mit 'l' machen.

Da musst Du wohl nochmal drüber nachdenken, unter welchen Umständen Du welche Zeichen entfernt haben möchtest und den Quelltext entsprechend ändern.

Wobei mir gerade auffällt, das mein Quelltext da einen Fehler hat:

Code: Alles auswählen

soup = BeautifulSoup(html, convertEntities=BeautifulSoup.HTML_ENTITIES) 

for td_node in soup('td'): 
    if td_node.has_key('height'): 
        print 
        class_ = td_node.get('class') 
        for character in 'xl': 
            if class_.startswith(character): 
                class_ = class_[1:]
            else:
                break
        print 'Gruppe:', class_ 
    content = ''.join(td_node(text=True)) 
    if content.strip(): 
        print 'Inhalt:', content
de_master
User
Beiträge: 72
Registriert: Samstag 15. Januar 2005, 15:19

Sorry,
mein Fehler. Das "xl" muss immer weg. Hab das "l" mal wieder als eine "1" gelesen :(. Dann stimmts so wies ist.

Gruss Michael
de_master
User
Beiträge: 72
Registriert: Samstag 15. Januar 2005, 15:19

Nun habe ich den Code in eine Klasse gepackt. Dabei habe ich bei der Zeile "content = ''join(td_node(text=True))" ein kleines Problem mit der Syntax.

In Zeile 28 erhalte ich den Syntax Fehler. Alles probiert, jedoch hat leider nichts geklappt :(.

Hier der Code: http://www.ubuntuusers.de/paste/8463/

Vielen Dank, Gruss Michael
BlackJack

Da fehlt ein Punkt. Du willst die `join()`-Methode auf einer Zeichenkette aufrufen. Die Methode ist ein Attribut des Zeichenketten-Objekts und Attributzugriff drückt man mit dem Punktoperator aus.

Da sind aber noch mehr Fehler. Man sollte nicht einfach überall ``self.`` davor schreiben. Du musst Dir klar machen was Attribute des Objekts sind bzw. sein sollen und was lokale Namen, die nur innerhalb der Methode Sinn machen und ausserhalb niemanden etwas angehen.
de_master
User
Beiträge: 72
Registriert: Samstag 15. Januar 2005, 15:19

Jap Danke. Nun funktionierts. Hier der Code:

http://www.ubuntuusers.de/paste/8465/

Gruss Michael
Antworten