php.de

Zurück   php.de > Webentwicklung > Software-Design

Software-Design Diskussionen auf Profi-Niveau: PHP Lösungen auf konzeptioneller Ebene

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 23.11.2009, 10:11  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.637
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekannt
Standard [Erledigt] Konzept für einen PHP Web Crawler

Servus

Ich arbeite gerade an einem Web Crawler auf PHP Basis und habe einige konzeptionelle Probleme und hoffe ihr könnt mir weiterhelfen.

Zielsetzung ist eine Datenbank mit möglichst vielen Links und entsprechenden Zuweisungen (von welcher URL wird auf welche verwiesen, welche URLs gehören zu welcher Domain etc). Das ganze wird für eine Art Statistik benötigt.

Meta-Tags wie Keywords oder gar Seiteninhalt, Bilder etc. sind vorerst irrelevant was die meisten "fertigen" Crawler schon einmal ausschließt. Es soll ein Maximum an Performance erreicht werden was durch Speicherung unnötiger Daten natürlich verfehlt wird.

Das derzeitige Konzept und der Stand des Testcodes sieht folgendermaßen aus:

Prinzipiell gibt es 3 "wichtige" ausführbare PHP Dateien: command.php - daemon.php und crawler.php.

- crawler.php

Dieser Datei wird eine URL als Parameter übergeben. Das Script pürft zunächst die Existenz von URL und der Domain in der Datenbank und nimmt ggf. beide Einträge vor. Danach wird ein HTTP Request via cURL durchgeführt und der Quelltext nach URLs mit dem HTTP/HTTPS Protokoll durchsucht. Die Domains werden ihrerseits in die Datenbank eingetragen wenn sie noch nicht vorhanden sind, ebenso ihre Domains.

Des weiteren wird in einer weiteren Datenbanktabelle ein Eintrag für die daemon.php angelegt, dass eine weitere URL zum crawlen vorliegt.

- daemon.php

Diese Datei durchläuft eine Schleife, solange bis in der Datenbanktabelle für die Aufgaben des Daemon der Befehl zum Beenden eingetragen wird. Pro Schleifendurchlauf wird eine Aufgabe aus der Aufgabentabelle entnommen. Handelt es sich dabei um eine Crawler Aufgabe startet das Script einen weiteren PHP Prozess im Hintergrund um die URL zu verarbeiten (crawler.php).

- command.php

Dieses Script dient zur Steuerung des ganzen. Hierüber können neue Instanzen der daemon.php gestartet und beendet werden.

-------------------------------

Der Crawler lief gestern mit 20 daemon.php Instanzen und insgesamt ca. 500 - 600 Prozessen anfangst reibungslos. Ab ca. 150000 URLs in der Datenbank kam es nun dazu das für verschiedene daemon.php Instanzen die gleichen URLs als Aufgaben vorlagen - soweit kein Problem da URL-Existenz immer vorher abgefragt wird - aber eben unperformant da der crawler.php Prozess vorher gestartet werden muss bevor die URL als "existent" erkannt wird.

Außerdem gibt es Probleme wenn die URLs welche als Aufgabe eingetragen wurden keine "neuen" URLs mehr enthalten. Dann bleiben die daemon.php Prozesse hängen (heute morgen hatten noch 2 von 20 Aufgaben zum abarbeiten).

Eigenständig aus der URL Tabelle URLs entnehmen dürfen die Daemons nicht, denn dann kommt es dazu das mehrere Daemons genau die gleichen URLS ablaufen und die Crawler Prozesse sich gegenseitig behaken (hatte schon doppelte Primary Keys und sonstige Datenbankfehler...).

Was meint ihr zu dem Konzept und wie würdet ihr vorgehen? Das Grundprinzip ist ja relativ einfach: URL speichern -> Sourcecode parsen -> URLS speichern -> Neue URLs durchlaufen -> Sourcecode parsen... da aber so viele URLS wie möglich zeitgleich abgearbeitet werden sollen wird das ganze schwierig.
Dark Guardian ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 23.11.2009, 11:02  
da schreibt der ElePHPant
 
Benutzerbild von Flor1an
 
Registriert seit: 18.06.2008
Beiträge: 8.903
PHP-Kenntnisse:
Fortgeschritten
Flor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer Anblick
Standard

Wieso möchtest du so einen Crawler in PHP schreiben? PHP unterstützt weder Threads noch neben läufige Abarbeitung von Aufgaben.

Würdest du auf eine Sprache setzen die Threads unterstützt würde sich das Problem bestimmt einfacher lösen. Mit Java könntest du z.B. Threads für jede URL starten, begrenzt auf x Threads und sobald die URL fertig ist bekommt der Thread entweder ne neue URL oder beendet sich. Des weiteren kannst du mit Java Racing Conditions unterbinden (synchronize method etc.) und hast nich das Problem das Threads eine bestimmte URL doppelt parsen wollen.

Ich würde es dann so machen dass dein "Controller" eben x Threads startet und selbst eine Liste mit den URLs verwaltet die noch nicht gecrawled wurden. Das hinzufügen und entnehmen der Elemente machen dann die einzelnen Threads, allerdings über so eine synchronized Methode um Racing Conditions zu vermeiden. Die Threads selber speichern die fertigen URLs dann in der Datenbank. Zur Not könnte der Controller zusätzlich zu seiner Liste die URLs noch in eine Datenbank schreiben falls er mal beendet werden sollte.

Meiner Meinung nach ist PHP für solche Aufgaben denkbar ungeeignet da du mehrere Aufgaben nicht wirklich gut steuern kannst.

Geändert von Flor1an (23.11.2009 um 11:07 Uhr).
Flor1an ist offline   Mit Zitat antworten
Alt 23.11.2009, 12:40  
Erfahrener Benutzer
 
Benutzerbild von Dark Guardian
 
Registriert seit: 10.10.2009
Beiträge: 2.637
PHP-Kenntnisse:
Fortgeschritten
Dark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekanntDark Guardian ist jedem bekannt
Standard

Eine andere Sprache wäre sicher geeigneter, nur kann ich außer PHP nur Delphi ausreichend genug im Multithreading umzusetzen - und dort bin ich ledeglich in der Windoof Programmierung eingearbeitet und der Crawler sollte nach Möglichkeit sowohl auf Linux als auch auf Windoof Servern/Rechnern laufen (so kann ich meine PrivatPCs und ggf. einige Firmen PCs zum "mitcrawlen" nutzen).

Es gibt auch bereits einige PHP Crawler... nur tun die leider viel mehr als nötig ist. Außerdem habe ich gerne den Lerneffekt dabei...

Ich habe noch ein wenig gesucht und bin auf die Funktion proc_open() gestoßen:

PHP: proc_open - Manual

Wenn ich das Manual richtig verstehe müsste sich damit doch eine Art Threading erzeugen lassen. Die Crawler-Prozesse laufen dann ebenfalls in einer Schleife, solange bis der Controller ihnen sagt das sie stoppen sollen. Damit könnte der Controller auch "richtig" kontrollieren und die Datenbank würde weniger belastet da die Prozesskommunikation dann direkt zwischen den Prozessen möglich ist.
Dark Guardian ist offline   Mit Zitat antworten
Alt 23.11.2009, 13:09  
da schreibt der ElePHPant
 
Benutzerbild von Flor1an
 
Registriert seit: 18.06.2008
Beiträge: 8.903
PHP-Kenntnisse:
Fortgeschritten
Flor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer Anblick
Standard

Dann ist jetzt doch der richtige Zeitpunkt mal eine neue Sprache anzuschauen. Schau dir doch mal Java an. Mit Eclipse hast du alles was du dafür brauchst. Threads sind auch relativ einfach mit Java zu realisieren da musst du nur ein kurzes Tutorial lesen und schon weißte wies geht. Wenn du ein Problem lösen möchtest dann such dir die entsprechenden Mittel dafür, nicht mit den Mittel die du hast versuchen Probleme zu lösen.
Flor1an ist offline   Mit Zitat antworten
Alt 23.11.2009, 14:00  
Moderator
 
Benutzerbild von robo47
 
Registriert seit: 03.09.2004
Beiträge: 11.792
PHP-Kenntnisse:
Fortgeschritten
robo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz sein
Standard

Wenn du dein Problem mit den "neuen Urls für Daemons" lösen willst, kannst du doch einfach einen speziellen Daemon starten der nichts anderes macht als neue Urls rauszugeben,
sprich die anderen Daemons melden sich bei dem und verlangen neue urls, dann ruft der Vergabe-Daemon XXX urls aus der datenbank ab die noch nicht abgearbeitet sind oder die mal wieder abgerufen werden müssen, marktiert sie in der datenbank als vergeben an Daemon #X mit nem timestamp.

Ansonsten kannst du ja auch für jede Instanz des Crawler eine "eigene" Datenquelle (Datei, Tabelle in der Datenbank, key in APC/Memcache ... ).

Sprich du hast z.b. in der Datenbank eine tabelle:

id | url | daemon | done

dort holt sich jeder Daemon die ihm zugeordneten Urls ab, verarbeitet sie und setzt danach done auf 1 und time auf ide uhrzeit wo er fertig wurde.

Ein anderes script ruft regelmäßig (cron oder auch permanent laufend) die tabelle ab, entfernt alles was done ist und trägt wieder neue urls ein aus der haupttabelle.
robo47 ist offline   Mit Zitat antworten
Alt 23.11.2009, 14:29  
da schreibt der ElePHPant
 
Benutzerbild von Flor1an
 
Registriert seit: 18.06.2008
Beiträge: 8.903
PHP-Kenntnisse:
Fortgeschritten
Flor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer Anblick
Standard

Mh problematisch wirds dann wenn die Tabelle aber gleichmässig von allen Daemons abgearbeitet wird. Angenommen der erste sucht sich eine URL -> fängt an zu arbeiten. In der Zeit kommen die andren Daemons, sehen die URL ist noch nicht bearbietet, holen sich die selbe aus der Datenbank -> arbeiten auch. Nun schreibt der erste in die DB das die URL bearbeitet ist. Trotzdem arbeiten immer noch zig Daemons die selbe URL ab.

Meiner Meinung nach sollte das schon in der DB vermerkt werden sobald die URL entnommen wird. Und daher ist es besesr mit Sprachen zu arbeiten die bestimmte Aktionen als atomar beschreiben kann um solche Race Conditions zu vermeiden.
Flor1an ist offline   Mit Zitat antworten
Alt 23.11.2009, 14:38  
Moderator
 
Benutzerbild von robo47
 
Registriert seit: 03.09.2004
Beiträge: 11.792
PHP-Kenntnisse:
Fortgeschritten
robo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz sein
Standard

Zitat:
Zitat von Flor1an Beitrag anzeigen
Mh problematisch wirds dann wenn die Tabelle aber gleichmässig von allen Daemons abgearbeitet wird. Angenommen der erste sucht sich eine URL -> fängt an zu arbeiten. In der Zeit kommen die andren Daemons, sehen die URL ist noch nicht bearbietet, holen sich die selbe aus der Datenbank -> arbeiten auch. Nun schreibt der erste in die DB das die URL bearbeitet ist. Trotzdem arbeiten immer noch zig Daemons die selbe URL ab.

Meiner Meinung nach sollte das schon in der DB vermerkt werden sobald die URL entnommen wird. Und daher ist es besesr mit Sprachen zu arbeiten die bestimmte Aktionen als atomar beschreiben kann um solche Race Conditions zu vermeiden.
Deshalb ja die spalte daemon, die setzt nicht der crawler-daemon sondern das "Verteilungsscript" das die Tabelle auch wieder auffüllt (für die Daemons die abgearbeitete haben, werden neue eingefügt)
robo47 ist offline   Mit Zitat antworten
Alt 23.11.2009, 15:00  
da schreibt der ElePHPant
 
Benutzerbild von Flor1an
 
Registriert seit: 18.06.2008
Beiträge: 8.903
PHP-Kenntnisse:
Fortgeschritten
Flor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer Anblick
Standard

Und wie soll das dann ablaufen? Soll das Verteilundsscript einmal gestartet werden und dann immer an die Daemons verteilen (wie soll das gehn?) oder rufen die Daemons das Verteilungsscript auf (dann haste wieder das Problem mit den Race Cond.)?
Flor1an ist offline   Mit Zitat antworten
Alt 23.11.2009, 15:16  
Moderator
 
Benutzerbild von robo47
 
Registriert seit: 03.09.2004
Beiträge: 11.792
PHP-Kenntnisse:
Fortgeschritten
robo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz seinrobo47 kann auf vieles stolz sein
Standard

Verteilungsscript -> läuft permanent oder via cronjob alle XX Zeiteinheiten, es sorgt nur dafür dass in der zuteiltungstabelle alle einträge die done = 1 haben entfernt werden und dann wird geschaut dass für jeden Daemon wieder XXXXX einträge drin sind.

Daemons rufen sich regelmäßig nach XX urls die sie gecrawlt haben aus dieser tabelle via

SELECT bla, foo FROM zuteiltungstabelle WHERE deamon='%DAEMONID%'

es findet also keine interaktion direkt zwischen daemon und verteilungsscript statt.
robo47 ist offline   Mit Zitat antworten
Alt 23.11.2009, 15:46  
da schreibt der ElePHPant
 
Benutzerbild von Flor1an
 
Registriert seit: 18.06.2008
Beiträge: 8.903
PHP-Kenntnisse:
Fortgeschritten
Flor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer AnblickFlor1an ist ein wunderbarer Anblick
Standard

Okay so würde das Sinn machen. Allerdings muss man dann aufpassen dass die Tabelle immer gleich auf die Daemons verteilt wird (falls die Daemons gleich schnell rechnen) falls nicht muss man da irgendwie ein Ranking rein bekommen damit nicht irgendwann ein schneller Daemon keine Einträge mehr hat.
Flor1an ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[Tipp?] Website Crawler der.. PatrickXX30 Off-Topic Diskussionen 3 11.11.2009 08:57
MVC Konzept Babbsdrebbler Software-Design 6 30.10.2009 08:13
Konzept für Bowsergame Wiillli Beitragsarchiv 1 21.10.2009 15:18
Grafiker gesucht - BG mit fertigem Konzept und Programmierern thezug Beitragsarchiv 0 28.08.2009 15:33
Besucher Name/Ip ändern mqs PHP Tipps 2009 6 26.06.2009 12:27
[Erledigt] Konzept Newssammler larsemann PHP-Fortgeschrittene 8 03.03.2009 17:20
kleines DB Konzept Tomte Datenbanken 21 23.08.2008 10:22
dynamische Webseiten - Sitemap: Konzept dh1sbg PHP-Fortgeschrittene 4 14.08.2007 13:23
Konzept Frage (2), DB Package greg PHP-Fortgeschrittene 0 15.07.2006 14:19
Überdenken des Konzept: Eigene Bildergalerien für User pixelcut PHP-Fortgeschrittene 3 16.01.2006 18:40
Konzept GFX-Community PHP Tipps 2005-2 2 22.08.2005 10:22
Suche Link Crawler Beitragsarchiv 2 22.06.2005 08:36
[Erledigt] Selectanfrage an eine Datenbank,aber aus mehreren Tabellen Datenbanken 2 26.10.2004 07:23
[Erledigt] Probleme beim Umsetzen von alten Konzept in Smarty PHP-Fortgeschrittene 4 13.09.2004 01:43
[Erledigt] Multigaming Warscript Konzept PHP-Fortgeschrittene 6 30.08.2004 20:56

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
php crawler, php crawler tutorial, webcrawler php, crawler schreiben, php webcrawler, crawler php, php web crawler, webcrawler schreiben, webcrawler programmieren, php website crawler, web crawler php, website crawler php, crawler php schreiben, php crawler schreiben, webcrawler tutorial, crawler in php, php webcrawler tutorial, http://www.php.de/software-design/61524-erledigt-konzept-fuer-einen-php-web-crawler.html, crawler php tutorial, php web crawler tutorial

Alle Zeitangaben in WEZ +2. Es ist jetzt 00:36 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum