Seite 1 von 1

Crawler funktioniert "halb"

Verfasst: Freitag 12. September 2008, 20:57
von nemomuk
Hallo,

in meinen letzten beiden Beiträgen ging es ja schon teilweise um einen "URL-Crawler"... Nun habe ich mir vorerst mal einen ganz simplen gebaut, der eine Domain ganz abgrast und einliest und als nächstes dann die nächste komplett... usw. (Datenbankanbindung etc. kommt alles noch) Mir geht es jetzt erstmal darum, dass alles funktioniert - das crawlen an sich.

Wenn man jetzt zB die Seite www.icoost.com crawlt funktioniert das perfekt. Er fundet alle Seiten...
Nun gibt es als erstes mal ein paar Fragen:
- Hat ein Dictionary in Python eine maximale Größe (hab mal 3h das Skript auf einer großen internetSeite laufen lassen und habe noch keine Grenze entdecken können...?
- Gibt es eine einfache Möglichkeit Frames zu parsen?
- wenn ich als Startdomain zB http://de.wikipedia.org/ angebe, erhalte ich ein forbidden, warum (mit urllib2)?
- gibt es eine einfach möglichkeit auf Weiterleitungen einzugehen?

Problem:
- wenn ich http://www.serversupportforum.de/ als Startpunkt festlege findet er 0 Links/Seiten... mir ist ein Rätsel warum...
- viele Seiten haben eine Sperre an maximalen Seitenaufrufen pro Minute..., wie zB Wikis oder ähnliche... Wie könnte man das effektiv umgehen - besser nicht eine Domain komplett parsen, sondern warten... und wo anders weitermachen?

Danke!
MfG

Ganz vergessen, das Skript: http://paste.pocoo.org/show/85148/

Verfasst: Freitag 12. September 2008, 22:06
von BlackJack
Du solltest auf jeden Fall mal http://de.wikipedia.org/wiki/Robots_Exclusion_Standard durchlesen.

Wikipedia wird Dein User-Agent-Header wahrscheinlich nicht gefallen.

Du solltest auch bei Seiten die nicht Sperren wenn man in kurzer Zeit viel runterlädt nicht so schnell runterladen wie Du kannst. Irgend wen kostet Webtraffic letztendlich auch immer Geld!

Dictionaries haben eine maximale Grösse. Auf 32-Bit-Systemen sind das AFAIK ca. 2 Milliarden Einträge, allerdings dürfte da das RAM bzw. der Adressraum für einen einzelnen Prozess früher eine Grenze setzen.

Verfasst: Freitag 12. September 2008, 22:33
von nemomuk
Danke für deine Hilfe...

Hast du eine Ahnung warum er auf bestimmten Seiten gar keine links findet... (zB serversupportforum.de)?

Verfasst: Samstag 13. September 2008, 00:04
von Leonidas
Vielleicht liefert ja das Forum keinen Content an deinen Useragent. Vielleicht ist es einfach ein Bug in deinem Programm.

Wenn du einen Request machst, dann untersuchst du die Reponse und guckst ob es eine Weiterleitung ist - fertig.

Frames.. hmm, wie war das noch mal - jetztendlich hast du in einem Frame mehrere Dokumente geladen die Links enthalten. Diese Dokumente läufst du alle entlang.

Und, ähm, immer in eine Datenstruktur wie ein Dictionary reinzufüllen ohne da was rauszunehmen ist auch keine generell empfehlenswerte Idee, zudem so ein Dictionary keinerlei Persistenz bietet und bei einem Crash alles weg ist. Da schon besser Shelve oder etwas wie die SimpleDB nutzen. Wobei ich auch mit BeautifulSoup bei langlaufenden Prozessen etwas vorsichtig wäre, das kann möglicherweise Speicher leaken.

Verfasst: Samstag 13. September 2008, 07:19
von nemomuk
ich hatte ja gesagt: vorläufige Version...

Ich wollte nach einem kompletten Domain "crawling" das dict in die db speichern, um so sicherzustellen, dass er für die Linksuche nicht ganz so lang bleibt und dachte ein dict ist schneller als die db Anbindung...

Content wird definitiv ausgeliefert, das habe ich als erstes getestet...;) Kann es sein, dass BeautifulSoup mit dem Dokument ein Problem hat oder bestimmte nicht parsen kann?

Vielen Dank!!!

Verfasst: Samstag 13. September 2008, 08:16
von __marcus__
Warum nimmst Du überhaupt BS, wenn Du eh nur Links bzw. das, was in irgendeines Elements 'src' steht, haben willst?

Verfasst: Samstag 13. September 2008, 08:54
von nemomuk
da hast du eigentlich recht... mit einem einfachen RE würde das vllt. bessere Ergebnisse liefern...

edit: und siehe da ich kann auch die eine seite crawlen...
re.compile('href=[\"\'](.*?)[\"\']', re.I)

Verfasst: Samstag 13. September 2008, 10:02
von HWK
Vielleicht etwas besser so:

Code: Alles auswählen

re.compile('href=(?P<quote>[\"\'])(.*?)(?P=quote)', re.I)
MfG
HWK

Verfasst: Samstag 13. September 2008, 10:04
von __marcus__
Vor allem beschleunigt BS die Sache ja nicht.

Kannst ja auch mal das probieren:

Code: Alles auswählen

"/(?:=\s{0,}(?:'|\")?|\(\s{0,}(?:'|\"))(?=[^\s'\">,]+\.)([^\s'\">?#=();]+(?(?=[\s'\">])|(?=[?#])[^\s'\">]+))/x"
Hat allerdings Probleme mit URLs in denen ein Komma ist, was ich allerdings erst später festgestellt habe, wo ich das selber schon wieder nicht mehr verstanden habe, was da passiert...

Verfasst: Samstag 13. September 2008, 12:51
von nemomuk
__marcus__ hat geschrieben:Vor allem beschleunigt BS die Sache ja nicht.

Kannst ja auch mal das probieren:

Code: Alles auswählen

"/(?:=\s{0,}(?:'|")?|\(\s{0,}(?:'|"))(?=[^\s'">,]+\.)([^\s'">?#=();]+(?(?=[\s'">])|(?=[?#])[^\s'">]+))/x"
Hat allerdings Probleme mit URLs in denen ein Komma ist, was ich allerdings erst später festgestellt habe, wo ich das selber schon wieder nicht mehr verstanden habe, was da passiert...
Was macht dieses Konstrukt hier genau?^^

Verfasst: Samstag 13. September 2008, 12:55
von __marcus__
Es findet URLs in meta-Links, src, href, Javascript - so lange sie da nicht zusammen gesetzt werden und ich glaube sogar im Klartext. Aber wie gesagt, man muss sich da ein wenig reinfuchsen.

Verfasst: Samstag 13. September 2008, 13:01
von nemomuk
und was für einen genauen Vorteil hat es nun gegenüber meiner oder HWKs Methode? Konnte keinen erkennen...

Verfasst: Samstag 13. September 2008, 13:28
von Leonidas
Man könnte sich aber auch mit ET/lxml das Leben einfacher machen. Dann muss man zwar mehr definieren, aber es ist einfacher zu maintainen und zu verstehen.

Verfasst: Samstag 13. September 2008, 14:15
von __marcus__
SchneiderWeisse hat geschrieben:und was für einen genauen Vorteil hat es nun gegenüber meiner oder HWKs Methode? Konnte keinen erkennen...
Wenn Du wirklich nur das finden willst, was auch wirklich ein Link ist, den man anklicken könnte, dann hat es sogar nur Nachteile.