Seite 1 von 1

String Funktionen

Verfasst: Mittwoch 28. Februar 2007, 11:35
von de_master
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

Verfasst: Mittwoch 28. Februar 2007, 11:53
von Byte
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

Verfasst: Mittwoch 28. Februar 2007, 12:16
von Dill
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

Verfasst: Mittwoch 28. Februar 2007, 12:53
von 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' ')]

Verfasst: Mittwoch 28. Februar 2007, 21:08
von de_master
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

Verfasst: Mittwoch 28. Februar 2007, 22:48
von 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.

Verfasst: Mittwoch 7. März 2007, 17:22
von de_master
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

Verfasst: Mittwoch 7. März 2007, 17:43
von nkoehring
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)']

Verfasst: Mittwoch 7. März 2007, 20:34
von 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.

Verfasst: Mittwoch 7. März 2007, 21:59
von de_master
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

Verfasst: Dienstag 20. März 2007, 09:33
von de_master
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

Verfasst: Dienstag 20. März 2007, 11:19
von 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

Verfasst: Dienstag 20. März 2007, 11:58
von de_master
Sorry,
mein Fehler. Das "xl" muss immer weg. Hab das "l" mal wieder als eine "1" gelesen :(. Dann stimmts so wies ist.

Gruss Michael

Verfasst: Dienstag 20. März 2007, 14:46
von de_master
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

Verfasst: Dienstag 20. März 2007, 15:22
von 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.

Verfasst: Dienstag 20. März 2007, 16:17
von de_master
Jap Danke. Nun funktionierts. Hier der Code:

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

Gruss Michael