findall für Anfänger

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.
shadow07
User
Beiträge: 43
Registriert: Sonntag 22. Februar 2009, 16:29

Montag 23. Februar 2009, 06:27

Hallo,

ich versuche seit Tagen, aus einer Website einzelne Infos auszulesen.
Es gibt zum Beispiel 5 mal eine solche Zeile:
<td class="odd preis_his">48,85 €</td>

ich versuche es (try and error) zum Beispiel so (habe extra die Sonderzeichen <>"& erst mal rausgelassen):

Code: Alles auswählen

import os, sys
from twisted.web.client import getPage
from twisted.internet import reactor
from re import sub, split, search, match, findall
from string import find, atoi, strip
import urllib, os, sys, tempfile

website = urllib.urlopen("http://www.test.php")
Zeilen = website.readlines()
res = findall(r'odd([^euro]*)', Zeilen)
res2 = = "%s %s %s %s %s %s" % (x[0],x[1],x[2],x[3],x[4],x[5])
print res2
ich vermute, da ist wohl mehr als nur ein Fehler drin?

sowas funktioniert in einem fremden script:

Code: Alles auswählen

x = findall(r'/bilder/zahlen/.*/(?P<zahlen>\d.*)\.gif',output
)



ja, ich habe die Suche benutzt (bin jetzt eher verwirrter als vorher)
nein, google hat moch nicht schlauer gemacht
sorry, bin absoluter Python-Anfänger und durch bisheriges arbeiten mit VB und ähnlichem tue ich mich sehr schwer
BlackJack

Montag 23. Februar 2009, 08:07

@shadow07: Ja da ist mehr als ein Fehler drin. Mindestens ein Syntaxfehler und ein `NamenError` in Zeile 11. Man kann nicht einfach zwei Gleicheitszeichen hintereinander schreiben, oder auf Namen zugreifen, die vorher nicht definiert wurden.

Bitte demnächst lauffähiges und möglichst minimales als Beispiel zeigen. Du hast da nämlich auch eine Menge Importe, die gar nicht verwendet werden.

Die Importe aus `string` sollte man auch nicht verwenden. `find()` und `strip()` sind als Methoden auf Zeichenketten vorhanden und statt `atoi()` kann man `int()` verwenden.

Der reguläre Ausdruch passt auf 'odd' gefolgt von beliebig vielen Zeichen, die nicht 'e', 'u', 'r', oder 'o' sind. Damit kommst Du in dem Beispiel genau bis zu dem 'p' von 'preis_his', weil danach eben ein 'r' kommt.

HTML mit regulären Ausdrücken zu vearbeiten ist aber auch keine so gute Idee. Benutze dafür lieber eine Bibliothek, die HTML versteht und genau für solche Aufgaben gedacht ist, wie `BeautifulSoup` oder `lxml.html`.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Montag 23. Februar 2009, 08:07

Hallo,

beim Parsen von Webseiten nicht mit RegExps arebeiten! Wir haben das Thema gefühlte 3x die Woche :-D

Such einfach mal per SuFu hier. Du machst das am besten mit lxml oder html5lib. Das wird in vielen Threads ausführlich erklärt!

Wollte zu dem Thema nicht mal irgend wer einen Beitrag im wiki schreiben oder in der FAQ?
Panke
User
Beiträge: 185
Registriert: Sonntag 18. März 2007, 19:26

Montag 23. Februar 2009, 08:08

Mit Beautifulsoup:

Code: Alles auswählen

soup = BeautifulSoup(seiten_text)
tds = soup.findAll('td', class="odd_preis_his")
Mit der Übergabe des class-Attributes bin ich mir nicht sicher, schau mal in der Doku nach.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 23. Februar 2009, 09:19

Hyperion hat geschrieben:Wollte zu dem Thema nicht mal irgend wer einen Beitrag im wiki schreiben oder in der FAQ?
In der FAQ ist doch ein Abschnitt. Ich kann ja nichts dafür das die niemand liest.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Montag 23. Februar 2009, 13:13

Leonidas hat geschrieben:
Hyperion hat geschrieben:Wollte zu dem Thema nicht mal irgend wer einen Beitrag im wiki schreiben oder in der FAQ?
In der FAQ ist doch ein Abschnitt. Ich kann ja nichts dafür das die niemand liest.
Ah ... da isser ja :-)
[wiki]FAQ#WieVerarbeiteIchWebseiten[/wiki]
shadow07
User
Beiträge: 43
Registriert: Sonntag 22. Februar 2009, 16:29

Montag 23. Februar 2009, 13:33

zuerst mal vielen Dank dafür, das ihr immer wieder durchgekaute Themen jedesmal neu zu erklären versucht.
1. xml-Parser fallen glaube ich aus, da die Seite dynamisch erstellt wird

2. ich habe kein lauffähiges script, ich habe ein script erstellt:
#!/bin/sh

wget -q "http://www.esyoil.com/heiz%C3%B6lpreise ... tal_e3.php" -O /tmp/heizoel3.txt

sed '{s/<[^>]*>//g;s/&euro;//g;s/&nbsp;//g;s/Heute//g;s/^[ \t]*//;1,134d;194,$d;137d;138d}' /tmp/heizoel3.txt >/tmp/datei01.txt

sed '{/^\s*$/d;s/^[ \t]*//;s/+/%2B/g;s/-/%2D/g}' /tmp/datei01.txt >/tmp/datei09.txt

a=$(sed -n '1p' datei09.txt)",%20%20"$(sed -n '2p' datei09.txt)
b="2000=%20%20%20"$(sed -n '3p' /tmp/datei09.txt)"%20%20%2F%20%20"$(sed -n '4p' /tmp/datei09.txt)"%20%20"$(sed -n '5p' datei09.txt)
c="2500=%20%20%20"$(sed -n '6p' /tmp/datei09.txt)"%20%20%2F%20%20"$(sed -n '7p' /tmp/datei09.txt)"%20%20"$(sed -n '8p' datei09.txt)
d="3000=%20%20%20"$(sed -n '9p' /tmp/datei09.txt)"%20%20%2F%20%20"$(sed -n '10p' /tmp/datei09.txt)"%20%20"$(sed -n '11p' datei09.txt)
e="3500=%20%20%20"$(sed -n '12p' /tmp/datei09.txt)"%20%20%2F%20%20"$(sed -n '13p' /tmp/datei09.txt)"%20%20"$(sed -n '14p' datei09.txt)
f="4000=%20%20%20"$(sed -n '15p' /tmp/datei09.txt)"%20%20%2F%20%20"$(sed -n '16p' /tmp/datei09.txt)"%20%20"$(sed -n '17p' datei09.txt)

wget "http://127.0.0.1/web/message?text=$c%0a ... &timeout=0" 2>/dev/null

dieses script benötige ich aber in Python, von welchem ich bis vor kurzem nicht mal was gehört habe
also habe ich versucht, aus anderen py-scripten zu erkennen, wie die von mir gewünschten Funktionen umgesetzt werden können, habe dann in den leider fast ausschließlich englischen Dokus endlos gesucht, ein paar hundert mal 'try and error' gespielt und mich nun entschlossen, euch um Hilfe zu bitten (Script-Sprachen nach Buch zu lernen ist mir noch nie gelungen, ich habe mir Beispiele gesucht, geändert und aus den Fehlern gelernt, aber hier stehe ich diesmal komplett auf dem Schlauch weil ich absolut keinen Plan hab und keinen Anfang finde)
Benutzeravatar
cofi
Moderator
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Montag 23. Februar 2009, 15:51

shadow07 hat geschrieben:1. xml-Parser fallen glaube ich aus, da die Seite dynamisch erstellt wird
Und wo ist das Problem? Ob die Seite dynamisch erzeugt wird ist komplett egal, das solltest du aber auch bemerkt haben, denn dein Shell Skript bearbeitet auch eine statische Seite ;) Nebenbei ist Beautiful Soup ein HTML Parser.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 23. Februar 2009, 16:14

Der FAQ-Eintrag sagt schon eigentlich alles was du brauchst: einen Parser (ich rate zu html5lib oder lxml.html) und du musst wissen was du aus dieser Seite auslesen willst (mit lxml ist es dann sehr einfach, da man einen CSS-Selektor nutzen kann oder wenn man etwas aufwändigeres haben will auch XPath einsetzen kann um einen bestimmten Knoten aus einer Seite auszulesen. Ist aber mit etwas spielerei in der Konsole (Interpreter nutzen!) durchaus machbar und simpel.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Montag 23. Februar 2009, 16:34

Leonidas hat geschrieben:... oder wenn man etwas aufwändigeres haben will auch XPath einsetzen kann um einen bestimmten Knoten aus einer Seite auszulesen. Ist aber mit etwas spielerei in der Konsole (Interpreter nutzen!) durchaus machbar und simpel.
Es gibt da ja auch einige nützliche Firefox-Plugins, mit denen man die XPath Ausdrücke an der Seite testen kann - die finde ich in dem Zusammenhang durchaus nützlich. Aber klar, rein in einer Konsole geht's natürlich auch.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 23. Februar 2009, 17:01

Ich für meinen Teil nutze wo es geht die CSS-Selektoren in der Konsole. Das hat den Vorteil dass es simpler ist (man braucht selten die vollen Möglichkeiten von XPath, da kann man zur Not auch mit Python das Ergebnis nochmal filtern) und dass ich genau das als Rausbekomme was das Skript dann auch rausbekommen sollte. Das spart Probleme bei Inkompatibilitäten (ich weiß nicht wie gut der Support von XPath in Firefox und lxml jeweils ist). Das es da Firefox-Plugins gibt wusste ich aber noch gar nicht. Wenn ich sowas genutzt habe, dann höchstens via jQuery + Firebug :)
My god, it's full of CARs! | Leonidasvoice vs Modvoice
shadow07
User
Beiträge: 43
Registriert: Sonntag 22. Februar 2009, 16:29

Montag 23. Februar 2009, 18:11

@BlackJack
vielen Dank für die konstruktive Hilfe, ich habe etwas aufgräumt, string-import entfernt und weiterprobiert und gelesen, ich komm auf keinen Zweig, ich kapiere den Aufbau der findall-Anweisung nicht

Code: Alles auswählen

#!/usr/bin/python
 
from twisted.web.client import getPage
from re import sub, split, search, findall, IGNORECASE
 
seite=getPage('http://www.esyoil.com/heiz%C3%B6lpreise/heiz%C3%B6l_Obermarchtal_e3.php')
x = findall(r'preis_his(?)',seite)
print x
das wichtigste, was ich im Moment brauche, ist die Syntax erklärt für doofe, ungefähr
x= findall(r'ab hier suchen(nicht suchen)das hier suchen', hier drin suchen)

@alle anderen
es ist zwar schön das man mir helfen will, aber bitte nicht nach dem Motto 'wie a funktioniert sagen wir nicht, benutze b'
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Montag 23. Februar 2009, 18:39

shadow07 hat geschrieben:es ist zwar schön das man mir helfen will, aber bitte nicht nach dem Motto 'wie a funktioniert sagen wir nicht, benutze b'
Warum nicht? Kennst du Module wie lxml überhaupt? Bei Python lauet das Motto: "Batteries included". Natürlich kannst du weiterhin versuchen, die Seite mit dem re-Modul zu parsen. Ob dir viele Leute dabei helfen wollen, weiß ich allerdings nicht. Aufgeschlossenheit und Flexibilität sind für eine gute Lösung (ist nicht unbedingt das gleiche wie funktionierende) notwendig.
DasIch
User
Beiträge: 2435
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Montag 23. Februar 2009, 19:21

shadow07 hat geschrieben:@alle anderen
es ist zwar schön das man mir helfen will, aber bitte nicht nach dem Motto 'wie a funktioniert sagen wir nicht, benutze b'
"a" funktioniert nicht.
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Montag 23. Februar 2009, 19:43

Und keinen Parser verwenden wollen, dafür aber getPage aus Twisted nehmen, obwohl Python sowohl ``urllib`` als auch ``urllib2`` hat ist auch irgendwie inkonsequent :roll: Aber vielleicht hat der OP ja irgendwelche sinnvollen Gründe dafür. Vielleicht mag er die uns sogar nennen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Antworten