Strings aus Liste lesen und weiterverarbeiten

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
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

Hi, ich bin gerade dabei einen Crawler zu schreiben, soweit funktioniert der
auch. Das Problem an dem ich jetzt sitze ist das ich zwar die Links der
StartURL bekomme ich aber diese Links nicht weiterverfolgen kann.

ich speichere die Links alle in temp4 jetzt versuche die Links in temp4
zu öffnen und nacheinander abzuarbeiten. Ich komme im Moment absolut nicht weiter.

Wäre echt toll wenn jemand einen Tipp für mich hat

McAce

Code: Alles auswählen

import urllib, htmllib, formatter 
from urlparse import urlparse

class EigenerParser(htmllib.HTMLParser):  # Parser Klasse
    
    def __init__(self, formatter):      #Initialisieren eines Objects
        htmllib.HTMLParser.__init__(self, formatter)  #gibt text an die superclasse
        self.links = []
                        
    def start_a(self, attrs):       #start um die Links auf der Startseite in liste zu schreiben   
                    for attr in attrs :
                        if attr[0] == "href" :         
                            self.links.append(attr[1]) 
                   
    def get_links(self):            
        return self.links
   
format = formatter.NullFormatter()
htmlparser = EigenerParser(format)

URL ="http://www.uni-due.de"
temp1 = urlparse(URL)[1]
temp2 = temp1.split(".")
tld = temp2[-1]
domain = temp2[-2]+"."+temp2[-1]
print "domain is: "+domain
f = urllib.urlopen(URL)         #Eingabe des Startlinks
htmlparser.feed(f.read())
htmlparser.close()

links = htmlparser.get_links()
for index, line in enumerate(links):
    if (line.split(":",1)[0])==("http")or(line.split(":",1)[0]=="https"):
    #print links[index]
        if (line.find(domain) == -1):
            temp3 = urlparse(line)
            temp4 = temp3[0]+"://"+temp3[1]
            print temp4 

for line in temp4:
    
    print line





            





Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

McAce hat geschrieben:ich speichere die Links alle in temp4 jetzt versuche die Links in temp4
zu öffnen und nacheinander abzuarbeiten. Ich komme im Moment absolut nicht weiter.
Woran denn genau?

Außerdem solltest du besser ``htmllib`` vergessen und stattdessen ``html5lib`` oder ``lxml.html`` verwenden, wenn du einen robusten und schnellen Parser haben willst.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

@McAce: Du solltest da etwas strukturierter herangehen und keinen Quelltext ausserhalb von Definitionen von Klassen, Funktionen, und Konstanten auf Modulebene haben. Dann wäre es auch einfach die selbe Funktion zum auswerten der ersten URL wieder auf weitere anzuwenden.

`htmllib` aus der Standardbibliothek kommt nur mit korrektem HTML zurecht, ist also für den Einsatz mit Webseiten aus der Realität nicht zu gebrauchen.

Die `get_links()`-Methode ist überflüssig, Du kannst auch direkt auf das `links`-Attribut zugreifen.

Dann solltest Du sinnvolle Namen verwenden. `temp` plus Nummer ist nicht wirklich hilfreich beim Lesen und verstehen des Quelltextes.

Der Code zum Testen ob die URL mit 'http:' oder 'https:' beginnt ist reichtlich umständlich. Schau doch mal was für Methoden `str` so bietet. Auch ob eine Zeichenkette in einer anderen enthalten ist lässt sich lesbarer gestalten als mit `find()`. Dafür gibt's den ``in``-Operator beziehungsweise ``not in`` wenn man das Gegenteil wissen möchte.

Die letzte Schleife iteriert über die Buchstaben einer Zeichenkette, nennt die aber `line`!?
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

Also ich bekomme die Liste temp4 einfach nicht eingelesen, wenn ich mit

Code: Alles auswählen

for line in temp4:
    
    print line
versuche nun die Liste temp4 einzulesen wird mir nur der letze Link
untereinander ausgegeben
bsp.
h
t
t
p
:

usw.
BlackJack

@McAce: `temp4` ist ja auch keine Liste sondern eine Zeichenkette. An welcher Stelle im Quelltext glaubst Du denn da eine Liste an den Namen zu binden!?
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Schau mal Zeile 38 an. Was ist temp4 eigentlich für ein Name?!
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

Ich weiß das die namen temp1 usw nicht gerade sehr güntig sind. Da ich erstmal den Überblick behalten wollte habe ich sie einfach durchnumeriert.

Ich fange gerade erst mit dem Programmieren an, bin also was die übersichtlichkeit angeht noch unerfahren.

Ich war der meinung das ich in Zeile38 eine Liste erstelle dies scheint aber nicht der Fall zu sein.
Wie bekomme ich denn die Links in eine Liste?

McAce
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Ich denke eher du willst einer Liste etwas anhängen. Also vorher eine Liste erstellen und dann daran mit `append` Sachen hinzufügen.


Achja, if braucht keine Klammern.
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Hab hier mal 2 Links für dich.

http://ms4py.org/2010/04/27/python-sear ... er-part-1/

Und hier ist der Quelltext vom aktuellen Stand, leider noch ziemlich unkommentiert :(
http://bitbucket.org/ms4py/pyseeek/src/ ... crawler.py

Bei Fragen kannst du dich gerne melden.

Achja, der Blogpost für diesen Teil des Codes kommt vermutlich noch im Laufe der Woche, eventuell schon heute oder morgen.
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

Danke für die Links werde ich mir gleich mal ansehen und durcharbeiten.
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

habe mir die Links mal angesehen aber ich glaube um das alles vernünftig zu verstehen brauche ich noch was Zeit.

Unterdessen habe ich auch an meinem Versuch weitergearbeitet.

Ich hänge ab Zeile 39 dort versuche ich die link_liste auszulesen um damit
weiterzuarbeiten. Das klappt auch soweit, nur ist es nicht genau das was ich möchte. Denn jetzt wird die erzeugte Liste ausgelesen, OK.
Nur hätte ich das gerne so das diese Liste wieder eingelesen und wieder verarbeitet wird usw.

Wo ist da mein Denkfehler?

McAce

Code: Alles auswählen

import urllib, htmllib, formatter 
from urlparse import urlparse

class EigenerParser(htmllib.HTMLParser):  # Parser Klasse
    
    def __init__(self, formatter):      #Initialisieren eines Objects
        htmllib.HTMLParser.__init__(self, formatter)  #gibt text an die superclasse
        self.links = []
                        
    def start_a(self, attrs):       #start um die Links auf der Startseite in liste zu schreiben   
                    for attr in attrs :
                        if attr[0] == "href" :         
                            self.links.append(attr[1]) 
                                                                                        
    def get_links(self):            
        return self.links
   
format = formatter.NullFormatter()
htmlparser = EigenerParser(format)

URL ="http://www.uni-due.de"
domain = urlparse(URL)[1].split(".")[-2]+"."+urlparse(URL)[1].split(".")[-1]
print "Startdomain ist ", domain

f = urllib.urlopen(URL)         #Eingabe des Startlinks

htmlparser.feed(f.read())
links = htmlparser.get_links()
link_liste=[]
for index, line in enumerate(links):
    if (line.split(":",1)[0])==("http")or(line.split(":",1)[0]=="https"):
        if (line.find(domain) == -1):
            link_liste.append(urlparse(line)[0]+"://"+urlparse(line)[1])
print "Link Liste", " Anzahl der links:", len(link_liste)
print link_liste 
print " "

for item in link_liste:
    f = urllib.urlopen(item)         
    htmlparser.feed(f.read())
    links = htmlparser.get_links() 
    link_liste=[]
    for index, line in enumerate(links):
        if (line.split(":",1)[0])==("http")or(line.split(":",1)[0]=="https"):
            if (line.find(domain) == -1):
                link_liste.append(urlparse(line)[0]+"://"+urlparse(line)[1])
    print link_liste
BlackJack

@McAce: Das habe ich doch schon geschrieben: Hör auf alles auf Modulebene zu machen und teile das Problem in sinnvolle Teilprobleme auf, die durch Funktionen gelöst werden.

Ausserdem hatte ich noch ein paar andere Hinweise gegeben…
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Hab meinen Crawler-Code noch einmal überarbeitet und dabei ziemlich vereinfacht. Ist jetzt außerdem ausführlich kommentiert.

http://bitbucket.org/ms4py/pyseeek/src/ ... crawler.py

Edit: Die Performance ist auch ganz nett

Code: Alles auswählen

Total runtime: 25 min
Pages processed: 1963
Average: 1.265 Pages/s 75.927 Pages/min
„Lieber von den Richtigen kritisiert als von den Falschen gelobt werden.“
Gerhard Kocher

http://ms4py.org/
McAce
User
Beiträge: 32
Registriert: Dienstag 20. April 2010, 14:01

Die Tipps hatte ich schon gelesen nur war mir gestern noch nicht 100%tig klar wie ich die umsetzen soll. Mit ner Menge ausprobieren habe ich das dann
doch soweit hinbekommen das das Prog jetzt erstmal läuft. So kann ich dann weiter experimentieren und Erfahrung sammeln.
Um dann einen optimierteren Crawler zu schreiben, der etwas mehr kann
und das effektiver.

Vielen Dank für die Hinweise.

@ms4py werde mir den nachher mal in Ruhe ansehen und studieren :-) Danke
Antworten