Seite 1 von 1
Anfängerfrage zu Regular Expressions
Verfasst: Donnerstag 18. August 2011, 13:37
von Jurudoca
Hallo Leute,
bin ziemlich neu dabei und habe eine Frage zu folgendem Code, der die Links einer Seite (NICHT!) ausgeben soll:
Code: Alles auswählen
from httplib import *
import re
def getLinks(url):
verb = HTTPConnection(url)
verb.request('GET','/')
antw = verb.getresponse()
html = antw.read()
p = re.compile('(?<=href=")(.*?)(?=")')
link_matches = p.findall(html)
for a in link_matches:
if a != re.compile('(?<=href=")(.*?)(?=")'):
print a
#print link_matches
getLinks('www.spiegel.de')
Warum gibt python mir keine leere Liste zurück, wenn ich über das "for Konstrukt" das Suchmuster wieder negativ als Filter verwende (oder besser gesagt...verwenden will!). Was macht Python hier?
Mein Ziel ist es, alle Links auszugeben, bloss nicht die, die auf die Seite selbst zeigen. Um das aber zu verstehen, wollte ich erst mal dieses Verhalten untersuchen ;-P
Vielen Dank...
Jurudoca
Re: Anfängerfrage zu Regular Expressions
Verfasst: Donnerstag 18. August 2011, 13:39
von Hyperion
Sinnvollerweise parst man HTML-Seiten mit einem entsprechenden Parser. lxml oder html5lib o.ä. Damit kannst Du Dir leicht alle Links rausfiltern und dann kommst Du ohne regExp an den Wert des href-Attributs. Bei diesem musst Du dann gucken, wie du die URL zerlegst.
Re: Anfängerfrage zu Regular Expressions
Verfasst: Donnerstag 18. August 2011, 13:42
von /me
Jurudoca hat geschrieben:Code: Alles auswählen
p = re.compile('(?<=href=")(.*?)(?=")')
link_matches = p.findall(html)
for a in link_matches:
if a != re.compile('(?<=href=")(.*?)(?=")'):
print a
Schau dir mal an, was du da eigentlich vergleichst. Du vergleichst ein kompiliertes Pattern mit einem String.
Re: Anfängerfrage zu Regular Expressions
Verfasst: Donnerstag 18. August 2011, 13:49
von pillmuncher
Re: Anfängerfrage zu Regular Expressions
Verfasst: Donnerstag 18. August 2011, 13:51
von Jurudoca
Danke für die schnellen Anworten!
@/me : an welcher Stelle kompiliert er das Pattern? *aufSchlauchSteh*...Das soll er ja nur in bezug auf a..?
@ hyperion danke für den Hinweis, werde mir die Libraries gleich anschauen...
Grüße
Jurudoca
Re: Anfängerfrage zu Regular Expressions
Verfasst: Donnerstag 18. August 2011, 14:33
von /me
Jurudoca hat geschrieben:an welcher Stelle kompiliert er das Pattern? *aufSchlauchSteh*...Das soll er ja nur in bezug auf a..?
Genau hier:
Re: Anfängerfrage zu Regular Expressions
Verfasst: Donnerstag 18. August 2011, 14:40
von Jurudoca
Die Documentation von html5lib ist ja echst spartanisch und die Beispiele funktionieren bei mir nicht sonderlich gut:
Code: Alles auswählen
import html5lib
f = open("http://www.spiegel.de/index.html")
doc = html5lib.parse(f)
gibt bei mir die Fehlermeldung:
f = open("
http://www.spiegel.de/index.html")
IOError: [Errno 22] invalid mode ('r') or filename: '
http://www.spiegel.de/index.html'
Was stimmt da nicht?
Liebe Grüße
Re: Anfängerfrage zu Regular Expressions
Verfasst: Donnerstag 18. August 2011, 14:49
von cofi
Das sagt die Doku:
Code: Alles auswählen
import html5lib
f = open("mydocument.html")
doc = html5lib.parse(f)
Nun vergleich das mal und schau dir die Fehlermeldung an.
Tipp: Du willst `urllib(2).urlopen` nutzen, nicht `open`.
Re: Anfängerfrage zu Regular Expressions
Verfasst: Freitag 19. August 2011, 10:24
von Jurudoca
@ me: dank Dir. ich glaube ich weiss was du meinst. Der Ausdruck steht für sich und macht rein gar nichts ;-P ? Wie kann ich erreichen, das er was macht? Mit re.search?
@cofi: uuuaah okay...das ist das lokale file! 'grrr'. Danke für den Hinweis! Kann man denn überhaupt mit html5lib eine Seite ähnlich wie mit urllib2.urlopen öffnen, oder ist html5lib gar nicht dafür gedacht, sondern quasi "nur" zur sinnvollen Weiterverarbeitung?
Danke Euch...das macht das Python erlernen echt angenehmer!
Re: Anfängerfrage zu Regular Expressions
Verfasst: Freitag 19. August 2011, 10:55
von cofi
Nein, html5lib ist "nur" ein Parser. Warum sollte es sich das auch aufbinden, wenn es eine schon eine funktionierende Infrastruktur in der Stdlib gibt?
Re: Anfängerfrage zu Regular Expressions
Verfasst: Freitag 19. August 2011, 10:57
von /me
Jurudoca hat geschrieben:@ me: dank Dir. ich glaube ich weiss was du meinst. Der Ausdruck steht für sich und macht rein gar nichts ;-P ? Wie kann ich erreichen, das er was macht? Mit re.search?
Ich verstehe dein Problem gerade nicht. Du hast
compile doch drei Zeilen darüber bereits korrekt verwendet.
Re: Anfängerfrage zu Regular Expressions
Verfasst: Freitag 19. August 2011, 11:23
von Jurudoca
/me hat geschrieben:
Ich verstehe dein Problem gerade nicht. Du hast compile doch drei Zeilen darüber bereits korrekt verwendet.
Dann kann ich das wohl nicht gut ausdrücken. Vielleicht hilft es, nochmal im Code zu sagen, was ich erreichen will:
Code: Alles auswählen
p = re.compile('(?<=href=")(.*?)(?=")')
link_matches = p.findall(html)
for a in link_matches:
if a != re.compile('(?<=href=")(.*?)(?=")'): # HIER WILL ICH, DASS a GEPRÜFT WIRD, OB ES MIT DEM RE.PATTERN ÜBEREINSTIMMT UND WENN JA, DANN PRINTET... DA ABER DAS MUSTER AUF ALLE LINKS ZUTRIFFT, DÜRFTE ER NICHTS AUSGEBEN ODER?...UND DAS FUNKTIONIERT NICHT
print a
Danke für die Mühe

Re: Anfängerfrage zu Regular Expressions
Verfasst: Freitag 19. August 2011, 11:25
von Jurudoca
cofi hat geschrieben:Nein, html5lib ist "nur" ein Parser. Warum sollte es sich das auch aufbinden, wenn es eine schon eine funktionierende Infrastruktur in der Stdlib gibt?
Habe dann das was Hyperion gesagt hat falsch verstanden:
hyperion hat geschrieben:Sinnvollerweise parst man HTML-Seiten mit einem entsprechenden Parser. lxml oder html5lib o.ä. Damit kannst Du Dir leicht alle Links rausfiltern und dann kommst Du ohne regExp an den Wert des href-Attributs. Bei diesem musst Du dann gucken, wie du die URL zerlegst.
Das gilt fürs parsen aber nicht fürs auslesen...Vestehe. Danke!
Re: Anfängerfrage zu Regular Expressions
Verfasst: Freitag 19. August 2011, 12:34
von /me
Jurudoca hat geschrieben:Code: Alles auswählen
p = re.compile('(?<=href=")(.*?)(?=")')
link_matches = p.findall(html)
for a in link_matches:
if a != re.compile('(?<=href=")(.*?)(?=")'): # HIER WILL ICH, DASS a GEPRÜFT WIRD, OB ES MIT DEM RE.PATTERN ÜBEREINSTIMMT UND WENN JA, DANN PRINTET... DA ABER DAS MUSTER AUF ALLE LINKS ZUTRIFFT, DÜRFTE ER NICHTS AUSGEBEN ODER?...UND DAS FUNKTIONIERT NICHT
Dann kommen wir mal zu einer Verständnisfrage. Was glaubst du, was dir
re.compile(...) als Ergebnis liefert?
Falls du meinst, dass es die gefundenen Muster sind, dann überlege dir, wofür du weiter oben
findall(...) verwendet hast und denk noch mal darüber nach.
Re: Anfängerfrage zu Regular Expressions
Verfasst: Freitag 19. August 2011, 13:19
von Jurudoca
/me hat geschrieben: Dann kommen wir mal zu einer Verständnisfrage. Was glaubst du, was dir re.compile(...) als Ergebnis liefert?
Okay sehe gerade ist ein Pattern Objekt <type '_sre.SRE_Pattern'> ;-P...
/me hat geschrieben: Falls du meinst, dass es die gefundenen Muster sind, dann überlege dir, wofür du weiter oben findall(...) verwendet hast und denk noch mal darüber nach.
Schwere Geburt...Danke für Deine Hilfe und das Fragen

:
Hier das Ergebnis, wie ich es mir vorgestellt habe:
Code: Alles auswählen
from httplib import *
import re
def getLinks(url):
verb = HTTPConnection(url)
verb.request('GET','/')
antw = verb.getresponse()
html = antw.read()
p = re.compile('(?<=href=")(.*?)(?=")')
link_matches = p.findall(html)
for a in link_matches:
i = p.findall(a)
print i
getLinks('www.spiegel.de')
Re: Anfängerfrage zu Regular Expressions
Verfasst: Freitag 19. August 2011, 13:36
von BlackJack
@Jurudoca: Was genau denkst Du was Du innerhalb der Schleife machst? Beziehungsweise was denkst du was `link_matches` enthält?
Und ich würde auch eher einen HTML-Parser verwenden, statt das mit regulären Ausdrücken zu lösen.
Re: Anfängerfrage zu Regular Expressions
Verfasst: Freitag 19. August 2011, 14:02
von Jurudoca
Haha...tja die schleife ist irgendwie unsinnig *bg* Danke für den Hinweis
Die HTML Parser sind glaube ich noch ein bisschen zu hoch für mich...Habe schon mit urllib2 herumgespielt...aber da brauche ich noch Zeit...
geht auch so:
Code: Alles auswählen
from httplib import *
import re
def getLinks(url):
verb = HTTPConnection(url)
verb.request('GET','/')
antw = verb.getresponse()
html = antw.read()
p = re.compile('(?<=href=")(.*?)(?=")')
link_matches = p.findall(html)
print link_matches
absurd = p.findall(str(link_matches))
print absurd
getLinks('www.spiegel.de')
jetzt muss ich es irgenwie hinbekommen, dass er die Links der eigenen Seite nicht mehr anzeigt, sondern nur noch die externen...das schaff ich hoffentlich bis heute Abend noch

Mein Ergebnis poste ich nochmal... Aber der Thread ist sowieso schon so lang...
Re: Anfängerfrage zu Regular Expressions
Verfasst: Freitag 19. August 2011, 14:24
von BlackJack
@Jurudoca: Das „geht” nur bedingt. HTML kann man nicht zuverlässig mit so einfachen regulären Ausdrücken parsen. Der Ausdruck den Du verwendest, kann sowohl Links übersehen, als auch falsche Treffer liefern. Es wird zum Beispiel nicht beachtet ob das Muster innerhalb eines Tags steht. Vorzugsweise eines Tags was nicht zufällig auskommentiert ist. Auf der anderen Seite kann der Wert des Attributs auch in einfache statt doppelter Anführungszeichen eingefasst sein, oder auch in gar keine. Das ist dann zwar kein gültiges HTML, aber solche kaputten Sachen findet man im Netz zuhauf.
Re: Anfängerfrage zu Regular Expressions
Verfasst: Freitag 19. August 2011, 14:36
von Jurudoca
@ Blackjack Ja das kann natürlich sein!
Wie würdest Du mit HTML Parsern vorgehen, um ein Programm zu schreiben was Links auf definierten Seiten zu externen Seiten ausgeben soll...
Welche Libs würdest du in welcher Reihenfolge dafür verwenden...?
Das Ding ist ja...ich will ja nicht html ausgeben sondern auslesen...
Grüße
Jurudoca
Re: Anfängerfrage zu Regular Expressions
Verfasst: Freitag 19. August 2011, 15:27
von BlackJack
@Jurudoca: Ich würde `lxml.html` oder `BeautifulSoup` zum Parsen und extrahieren der Links verwenden. Dann `urllib2.urlparse()` um die URLs in ihre Bestandteile zu zerlegen. Für die Daten sollte man Quelltext schreiben können, der interne von externen Links unterscheidet.