Links extrahieren mit SGMLLib

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.
rabby
User
Beiträge: 7
Registriert: Dienstag 13. Dezember 2005, 21:27
Kontaktdaten:

Links extrahieren mit SGMLLib

Beitragvon rabby » Dienstag 13. Dezember 2005, 21:32

hallo welt!
bin einsteiger in python und will in meinem aktuellen testscript alle urls einer html seite zuverlässig extrahieren.
habe lange mit regexp herumexperimentiert und will es nun noch mit dem parser von sgmllib versuchen. allerdings will das nicht so einfach klappen:

Code: Alles auswählen

class LinkExtractor(SGMLParser):
    def __init__(self):
   self.links = []
        SGMLParser.__init__(self)
    def do_a(self, attributes):
   for (name, value) in attributes:
       if name == "href":
      value = cleanlink(value)
                if value:
          self.links.append(value)
    def getlinks(self):
   return self.links
   
def get_links(src):
   parser=LinkExtractor()
   parser.feed(src)
   rueckgabe=parser.getlinks()
   return rueckgabe


könnte mir bitte jemand helfen, sodass die klasse wirklich funktionsfähig ist oder wie könnte man das einfacher schreiben? konnte keine funktionsfähigen beispiele finden :(
danke für Eure hilfe
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Re: Links extrahieren mit SGMLLib

Beitragvon gerold » Dienstag 13. Dezember 2005, 23:17

rabby hat geschrieben:alle urls einer html seite zuverlässig extrahieren.

Hi!

So etwas würde ich mit **BeautifulSoup** machen. Zu finden unter http://www.crummy.com/software/BeautifulSoup/.

Hier ein kleines Beispiel, das aufzeigt wie einfach so etwas mit dem richtigen Werkzeug sein kann. :wink: 8) :lol:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from BeautifulSoup import BeautifulSoup

html = """<html>
<head>
  <title>Hallo Welt</title>
</head>
<body>
  <p>
    <a href="http://www.bcom.at">Bcom</a>
    <a href="http://gerold.bcom.at">Gerold</a>
  </p>
  <p>
    <a href="http://sw3.at">SW3</a>
  </p>
</body>
</html>
"""
soup = BeautifulSoup(html)

# Alle Links raus suchen:
for anker in soup("a"):
    print "Text:", anker.string
    print "Href:", dict(anker.attrs)["href"]

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
rabby
User
Beiträge: 7
Registriert: Dienstag 13. Dezember 2005, 21:27
Kontaktdaten:

Beitragvon rabby » Mittwoch 14. Dezember 2005, 17:49

danke!

irgendwie gibt es probleme z.b. beim aufruf von ip-ermitteln.de :-(
was kann ich hierbei tun?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Mittwoch 14. Dezember 2005, 19:40

rabby hat geschrieben:irgendwie gibt es probleme z.b. beim aufruf von ip-ermitteln.de :-( was kann ich hierbei tun?

Hi rabby!

Wer kann denn ahnen, dass es so schrecklich formatierte Seiten gibt :?
Das Skript bleibt stehen, weil es einen Link findet, der kein "href"-Attribut besitzt.
Einfach diese Zeile ändern:

Code: Alles auswählen

print "Href:", dict(anker.attrs).get("href")

Mit einer guten IDE, mit der man auch debuggen kann, wärst du selber drauf gekommen.

KeyError: href
deutet darauf hin, dass der Key href nicht gefunden werden konnte.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Torsten2005
User
Beiträge: 34
Registriert: Mittwoch 2. November 2005, 15:37
Wohnort: Berlin
Kontaktdaten:

Beitragvon Torsten2005 » Mittwoch 14. Dezember 2005, 22:21

mm?
also warum geht das nicht so:

Code: Alles auswählen

link=findall('<a href=".+">', Stringwodertextdrinist)
liste=liste+['link']
BlackJack

Beitragvon BlackJack » Donnerstag 15. Dezember 2005, 00:50

Weil Du damit nicht alle Links findest. Erstens bekommst Du Probleme wenn in der gleichen Zeile nach dem ersten Link noch irgendwo ein `">` folgt weil reguläre Ausdrücke normalerweise "greedy" sind, also versuchen so viel wie möglich zu erkennen:

Code: Alles auswählen

In [10]: re.findall('<a href=".+">', '<a href="foo"> <div id="bar">')
Out[10]: ['<a href="foo"> <div id="bar">']


Das lässt sich mit einem Fragezeichen leicht beheben:

Code: Alles auswählen

In [11]: re.findall('<a href=".+?">', '<a href="foo"> <div id="bar">')
Out[11]: ['<a href="foo">']


Bleiben aber noch tausend andere Alternativen die nicht erkannt werden. Zum Beispiel wenn noch weitere Attribute im a-Tag sind, oder wenn statt der doppelten, einzelne Anführungszeichen, oder gar keine benutzt wurden.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Donnerstag 15. Dezember 2005, 02:20

Damit folgender Thread, der ja erst durch dieses Thema entstanden ist, nicht unter geht: http://www.python-forum.de/viewtopic.php?p=27720

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs

Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder