it-swarm.com.de

Entwerfen eines Web-Crawlers

Ich bin auf eine Interviewfrage gestoßen "Wenn Sie einen Web-Crawler entwerfen, wie würden Sie es vermeiden, in unendliche Schleifen zu geraten?", Und ich versuche es zu beantworten.

Wie fängt alles von vorne an an..__ Sagen Sie, Google habe mit einigen Hub-Seiten angefangen, sagen Sie hunderte davon (Wie diese Hub-Seiten überhaupt gefunden wurden, ist eine andere Unterfrage) . Wie Google auf Links folgt eine Seite und so weiter, erstellt sie weiterhin eine Hashtabelle, um sicherzustellen, dass sie nicht den zuvor besuchten Seiten folgt.

Was passiert, wenn auf derselben Seite zwei Namen (URLs) stehen, die in diesen Tagen bei URL-Verkürzungen usw. angezeigt werden?.

Ich habe Google als Beispiel genommen. Obwohl Google nicht leckt, wie seine Web-Crawler-Algorithmen und das Seitenranking usw. funktionieren, sondern irgendwelche Vermutungen?

65
xyz

Wenn Sie eine detaillierte Antwort erhalten möchten, werfen Sie einen Blick auf Abschnitt 3.8 dieses Dokuments , das den URL-Test eines modernen Scrapers beschreibt:

Beim Extrahieren von Links stößt jeder Webcrawler auf mehrere Links zu demselben Dokument. Um zu vermeiden, dass ein Dokument mehrmals heruntergeladen und verarbeitet wird, muss für jeden extrahierten Link ein URL-Test durchgeführt werden, bevor er zur URL-Grenze hinzugefügt wird. (Ein alternatives Design wäre, stattdessen den URL-Prüfungstest durchzuführen, wenn die URL von der Grenze entfernt wird, aber dieser Ansatz würde zu einer viel größeren Grenze führen.)

Um den URL-Prüfungstest durchzuführen, speichern wir alle von Mercator angezeigten URLs in kanonischer Form in einer großen Tabelle, der URL-Gruppe. Auch hier gibt es zu viele Einträge, als dass sie alle in den Arbeitsspeicher passen würden. Daher wird der URL-Satz wie der Dokument-Fingerabdrucksatz hauptsächlich auf der Festplatte gespeichert.

Aus Platzgründen speichern wir nicht die Textdarstellung jeder URL im URL-Satz, sondern eine Prüfsumme mit fester Größe. Im Gegensatz zu den Fingerabdrücken, die für den Dokumentfingerabdrucksatz des inhaltsgesehenen Tests angezeigt werden, weist der mit dem URL-Satz getestete URL-Stream eine nicht unbedeutende Menge an Lokalität auf. Um die Anzahl der Vorgänge auf der Sicherungsdatenträgerdatei zu verringern, wird daher ein speicherinterner Cache mit gängigen URLs gespeichert. Die Intuition für diesen Cache ist, dass Links zu einigen URLs recht häufig sind. Das Zwischenspeichern der gängigen URLs im Speicher führt daher zu einer hohen Trefferquote im Arbeitsspeicher.

Tatsächlich erreichen wir mit einem In-Memory-Cache von 2 ^ 18 Einträgen und der LRU-ähnlichen Taktersetzungsrichtlinie eine Gesamttrefferquote im In-Memory-Cache von 66,2% und eine Trefferquote von 9,5% in der Tabelle von Kürzlich hinzugefügte URLs für eine Netto-Trefferquote von 75,7%. Darüber hinaus führen etwa 1 = 3 der 24,3% der Anfragen, die sowohl im Cache der gängigen URLs als auch in der Tabelle der kürzlich hinzugefügten URLs fehlen, zu Puffertreffern in unserer Implementierung von Direktzugriffsdateien, die sich ebenfalls im Benutzerbereich befindet. Das Nettoergebnis all dieser Pufferung ist, dass jeder Mitgliedschaftstest, den wir für den URL-Satz durchführen, zu durchschnittlich 0,16 Such- und 0,17 Lesekernelaufrufen führt (von denen ein Teil aus den Dateisystempuffern des Kernels bereitgestellt wird). Jeder Mitgliedschaftstest für URL-Sets führt zu einem Sechstel aller Kernel-Aufrufe als Mitgliedschaftstest für den Dokument-Fingerabdruck-Set. Diese Einsparungen sind ausschließlich auf die Menge der URL-Lokalität (d. H. Die Wiederholung beliebter URLs) zurückzuführen, die dem URL-Stream beim Crawlen innewohnt.

Grundsätzlich werden alle URLs mit einer Hashing-Funktion gehasht, die eindeutige Hashes für jede URL garantiert. Aufgrund der Lokalität der URLs ist das Auffinden von URLs sehr einfach. Google hat sogar ihre Hashing-Funktion offen gelegt: CityHash

ACHTUNG!
Sie könnten auch über Botfallen sprechen !!! Ein Bot-Trap ist ein Abschnitt einer Seite, der ständig neue Links mit eindeutigen URLs generiert, und Sie werden im Wesentlichen in einer "Endlosschleife" gefangen, wenn Sie den Links folgen, die von dieser Seite bereitgestellt werden. Dies ist nicht gerade eine Schleife, da eine Schleife das Ergebnis des Besuchs derselben URL sein würde, aber es ist eine unendliche Kette von URLs, die Sie nicht crawlen sollten.

Update 13.12.2012- am Tag nachdem die Welt untergehen sollte :)

Per Kommentar von Fr0zenFyr: Wenn man den Algorithmus AOPIC zum Auswählen von Seiten verwendet, ist es ziemlich einfach, Bot-Traps der Art Endlosschleife zu vermeiden. Hier ist eine Zusammenfassung der Funktionsweise von AOPIC:

  1. Holen Sie sich einen Satz von N Startseiten.
  2. Ordnen Sie jeder Seite einen Kreditbetrag von X zu, sodass jede Seite einen Kreditbetrag von X/N (d. H. Den gleichen Kreditbetrag) hat, bevor das Crawlen begonnen hat.
  3. Wählen Sie eine Seite P aus, auf der P die höchste Gutschrift aufweist (oder crawlen Sie eine zufällige Seite, wenn alle Seiten dieselbe Gutschrift aufweisen).
  4. Crawl-Seite P (Angenommen, P hatte 100 Credits, als es gecrawlt wurde).
  5. Extrahieren Sie alle Links von Seite P (sagen wir, es gibt 10 davon).
  6. Setzen Sie die Credits von P auf 0.
  7. Nehmen Sie eine "Steuer" von 10% und ordnen Sie sie einer Lambda-Seite zu.
  8. Weisen Sie jedem Link, den Sie auf Seite P gefunden haben, den gleichen Betrag an Credits zu - die Steuer: also (100 (P Credits) - 10 (10% Steuer))/10 (Links) = 9 Credits pro Link.
  9. Wiederholen Sie ab Schritt 3.

Da die Lambda-Seite kontinuierlich Steuern erhebt, wird sie letztendlich die Seite mit dem höchsten Kreditbetrag sein und wir müssen sie "crawlen". Ich sage "crawlen" in Anführungszeichen, weil wir eigentlich keine HTTP-Anfrage für die Lambda-Seite stellen, sondern nur deren Credits nehmen und sie gleichmäßig an alle verteilen der Seiten in unserer Datenbank.

Da Bot-Traps nur interne Links gutschreiben und von außen nur selten gutgeschrieben werden, werden kontinuierlich Gutschriften (aus Steuern) an die Lambda-Seite weitergeleitet. Die Lambda-Seite verteilt diese Credits gleichmäßig auf alle Seiten in der Datenbank und mit jedem Zyklus verliert die Bot-Trap-Seite immer mehr Credits, bis sie so wenig Credits hat, dass sie fast nie wieder gecrawlt wird. Dies ist bei guten Seiten nicht der Fall, da sie häufig Gutschriften von Backlinks erhalten, die auf anderen Seiten gefunden wurden. Dies führt auch zu einem dynamischen Seitenrang, und Sie werden feststellen, dass Sie die Seiten jedes Mal, wenn Sie einen Schnappschuss Ihrer Datenbank machen, nach der Anzahl der Credits ordnen, die sie haben. Dann werden sie höchstwahrscheinlich grob nach ihrem True Page Rank .

Dies vermeidet nur Bot-Fallen der Endlosschleifen-Art, aber es gibt viele andere Bot-Fallen , auf die Sie achten sollten, und es gibt auch Möglichkeiten, sie zu umgehen.

81
Kiril

Während alle hier bereits vorgeschlagen haben, wie Sie Ihren Web-Crawler erstellen, wird hier die Reihenfolge der Seiten von Google erläutert.

Google gibt jeder Seite einen Rang basierend auf der Anzahl der Rückruf-Links (wie viele Links auf anderen Websites auf eine bestimmte Website/Seite verweisen). Dies wird als Relevanzwert bezeichnet. Dies basiert auf der Tatsache, dass eine Seite, auf die viele andere Seiten verlinkt sind, wahrscheinlich eine wichtige Seite ist.

Jede Site/Seite wird als Knoten in einem Diagramm angezeigt. Links zu anderen Seiten sind gerichtete Kanten. Ein Grad eines Scheitelpunkts ist als Anzahl der ankommenden Kanten definiert. Knoten mit einer höheren Anzahl ankommenden Flanken werden höher eingestuft.

So wird der PageRank ermittelt. Angenommen, die Seite Pj hat Lj-Links. Wenn einer dieser Links auf die Seite Pi verweist, gibt Pj 1/Lj seiner Wichtigkeit an Pi weiter. Das Wichtigkeitsranking von Pi ist dann die Summe aller Beiträge, die von den darauf verweisenden Seiten gemacht wurden. Wenn wir also den Satz von Seiten bezeichnen, die von Bi auf Pi verweisen, dann haben wir folgende Formel:

Importance(Pi)= sum( Importance(Pj)/Lj ) for all links from Pi to Bi

Die Ränge werden in einer Matrix namens Hyperlink-Matrix angeordnet: H [i, j]

Eine Zeile in dieser Matrix ist entweder 0 oder 1/Lj, wenn eine Verbindung von Pi zu Bi besteht. Eine weitere Eigenschaft dieser Matrix ist, dass wir 1 addieren, wenn wir alle Zeilen in einer Spalte summieren. 

Nun müssen wir diese Matrix mit einem Eigenvektor, genannt I (mit Eigenwert 1), so multiplizieren, dass

I = H*I

Nun beginnen wir zu iterieren: IH, I IH, I II H .... I ^ k * H, bis die Lösung konvergiert. dh wir bekommen in der Matrix in Schritt k und k + 1 so ziemlich die gleichen Zahlen.

Was im I-Vektor übrig bleibt, ist die Wichtigkeit jeder Seite.

Ein einfaches Beispiel für eine Hausaufgabengruppe finden Sie unter http://www.math.cornell.edu/~mec/Winter2009/RalucaRemus/Lecture3/lecture3.html

Um das doppelte Problem in Ihrer Interviewfrage zu lösen, führen Sie eine Prüfsumme auf der gesamten Seite aus und verwenden Sie entweder diese oder eine Bash der Prüfsumme als Schlüssel in einer Karte, um die besuchten Seiten zu verfolgen.

7
Adrian

Kommt darauf an, wie tief ihre Frage sein sollte. Wenn sie nur vermeiden wollten, denselben Links vor und zurück zu folgen, wäre das Hashing der URLs ausreichend.

Was ist mit Inhalten, die buchstäblich tausende URLs enthalten, die zum gleichen Inhalt führen? Wie ein QueryString-Parameter, der nichts beeinflusst, aber unendlich viele Iterationen haben kann. Ich vermute, Sie könnten auch den Inhalt der Seite mit einem Hash versehen und die URLs vergleichen, um zu sehen, ob sie ähnlich sind, um Inhalte zu erfassen, die durch mehrere URLs identifiziert werden. Siehe beispielsweise Bot Traps, die in @ Liriks Beitrag erwähnt werden.

1
mellamokb

Das Problem hierbei besteht nicht darin, doppelte URLS zu crawlen, die durch einen Index mit einem aus URLs erhaltenen Hash aufgelöst werden. Das Problem besteht darin, DUPLICATED CONTENT zu crawlen. Jede URL einer "Crawler-Falle" ist unterschiedlich (Jahr, Tag, SessionID ...).

Es gibt keine "perfekte" Lösung ... aber Sie können einige dieser Strategien anwenden:

• Behalten Sie ein Feld mit, auf welchem ​​Level sich die URL in der Website befindet. Erhöhen Sie für jedes Element, das URLs von einer Seite erhält, den Pegel. Es wird wie ein Baum sein. Sie können auf einer bestimmten Ebene, wie z. B. 10, mit dem Crawlen aufhören (ich denke, Google benutze dies). 

• Sie können versuchen, eine Art von HASH zu erstellen, die verglichen werden kann, um ähnliche Dokumente zu finden, da Sie nicht mit jedem Dokument in Ihrer Datenbank vergleichen können. Es gibt SimHash von Google, aber ich konnte keine Implementierung finden. Dann habe ich meine eigene erstellt. Mein Hashwert zählt niedrige und hohe Frequenzzeichen innerhalb des HTML-Codes und generiert einen 20-Byte-Hashwert, der mit einem kleinen Cache der letzten gecrawlten Seiten in einem AVLTree mit einer NearNeighbors-Suche mit etwas Toleranz (etwa 2) verglichen wird. Sie können keinen Verweis auf Zeichenstellen in diesem Hash verwenden. Nachdem Sie die Falle "erkannt" haben, können Sie das URL-Muster des doppelten Inhalts aufnehmen und damit beginnen, Seiten zu ignorieren.

• Wie bei Google können Sie für jede Website ein Ranking erstellen und mehr auf eine als "andere" vertrauen.

0
lexmooze

Sie müssten eine Art Hash-Tabelle haben, in der die Ergebnisse gespeichert werden. Sie müssen sie nur überprüfen, bevor die einzelnen Seiten geladen werden. 

0
chuchu

Ich musste auch den Crawler verwenden und kann nicht das richtige für meine Anforderungen finden. Danach habe ich eine grundlegende Crawler-Bibliothek entwickelt, um einfache Anforderungen zu implementieren. Sie können jedoch fast alle Prinzipien des Crawlers erfüllen. Sie können DotnetCrawler github repo überprüfen, die Downloader-Processor-Pipeline-Module mit der Standardimplementierung mithilfe von Entity Framework Core implementieren, um Daten in SQL Server zu speichern.

https://github.com/mehmetozkaya/DotnetCrawler

0
Mehmet Özkaya

Der Crawler führt einen URL-Pool, der alle zu durchsuchenden URLs enthält. Um eine "Endlosschleife" zu vermeiden, sollten Sie vor dem Hinzufügen zum Pool die Existenz jeder URL überprüfen.

Dies ist jedoch nicht einfach zu implementieren, wenn das System auf ein bestimmtes Maß skaliert wurde. Der naive Ansatz besteht darin, alle URLs in einem Hashsatz zu behalten und die Existenz jeder neuen URL zu überprüfen. Dies funktioniert nicht, wenn zu viele URLs in den Speicher passen.

Hier gibt es einige Lösungen. Anstatt alle URLs im Speicher abzulegen, sollten wir sie beispielsweise auf der Festplatte speichern. Um Platz zu sparen, sollte anstelle der Raw-URL ein URL-Hash verwendet werden. Es ist auch erwähnenswert, dass wir die kanonische Form der URL beibehalten sollten und nicht die ursprüngliche. Wenn also die URL von Diensten wie bit.ly verkürzt wird, ist es besser, die endgültige URL zu erhalten. Um den Überprüfungsprozess zu beschleunigen, kann eine Cache-Ebene erstellt werden. Oder Sie sehen es als verteiltes Cache-System, das ein separates Thema ist.

Der Beitrag Build a Web Crawler enthält eine detaillierte Analyse dieses Problems. 

0
Mark

Der Web-Crawler ist ein Computerprogramm, mit dem folgende Schlüsselwerte (HREF-Links, Bild-Links, Metadaten usw.) von einer bestimmten Website-URL gesammelt/gecrawlt werden. Es ist so konzipiert, dass es intelligent ist, verschiedenen HREF-Links zu folgen, die bereits von der vorherigen URL abgerufen wurden. Auf diese Weise kann Crawler von einer Website zu anderen Websites springen. Normalerweise wird es als Web-Spider oder Web-Bot bezeichnet. Dieser Mechanismus fungiert immer als Rückgrat der Websuchmaschine.

Den Quellcode finden Sie in meinem Tech-Blog - http://www.algonuts.info/how-to-built-a-simple-web-crawler-in-php.html

<?php
class webCrawler
{
    public $siteURL;
    public $error;

    function __construct()
    {
        $this->siteURL = "";
        $this->error = "";
    }

    function parser()   
    {
        global $hrefTag,$hrefTagCountStart,$hrefTagCountFinal,$hrefTagLengthStart,$hrefTagLengthFinal,$hrefTagPointer;
        global $imgTag,$imgTagCountStart,$imgTagCountFinal,$imgTagLengthStart,$imgTagLengthFinal,$imgTagPointer;
        global $Url_Extensions,$Document_Extensions,$Image_Extensions,$crawlOptions;

        $dotCount = 0;
        $slashCount = 0;
        $singleSlashCount = 0;
        $doubleSlashCount = 0;
        $parentDirectoryCount = 0;

        $linkBuffer = array();

        if(($url = trim($this->siteURL)) != "")
        {
            $crawlURL = rtrim($url,"/");
            if(($directoryURL = dirname($crawlURL)) == "http:")
            {   $directoryURL = $crawlURL;  }
            $urlParser = preg_split("/\//",$crawlURL);

            //-- Curl Start --
            $curlObject = curl_init($crawlURL);
            curl_setopt_array($curlObject,$crawlOptions);
            $webPageContent = curl_exec($curlObject);
            $errorNumber = curl_errno($curlObject);
            curl_close($curlObject);
            //-- Curl End --

            if($errorNumber == 0)
            {
                $webPageCounter = 0;
                $webPageLength = strlen($webPageContent);
                while($webPageCounter < $webPageLength)
                {
                    $character = $webPageContent[$webPageCounter];
                    if($character == "")
                    {   
                        $webPageCounter++;  
                        continue;
                    }
                    $character = strtolower($character);
                    //-- Href Filter Start --
                    if($hrefTagPointer[$hrefTagLengthStart] == $character)
                    {
                        $hrefTagLengthStart++;
                        if($hrefTagLengthStart == $hrefTagLengthFinal)
                        {
                            $hrefTagCountStart++;
                            if($hrefTagCountStart == $hrefTagCountFinal)
                            {
                                if($hrefURL != "")
                                {
                                    if($parentDirectoryCount >= 1 || $singleSlashCount >= 1 || $doubleSlashCount >= 1)
                                    {
                                        if($doubleSlashCount >= 1)
                                        {   $hrefURL = "http://".$hrefURL;  }
                                        else if($parentDirectoryCount >= 1)
                                        {
                                            $tempData = 0;
                                            $tempString = "";
                                            $tempTotal = count($urlParser) - $parentDirectoryCount;
                                            while($tempData < $tempTotal)
                                            {
                                                $tempString .= $urlParser[$tempData]."/";
                                                $tempData++;
                                            }
                                            $hrefURL = $tempString."".$hrefURL;
                                        }
                                        else if($singleSlashCount >= 1)
                                        {   $hrefURL = $urlParser[0]."/".$urlParser[1]."/".$urlParser[2]."/".$hrefURL;  }
                                    }
                                    $Host = "";
                                    $hrefURL = urldecode($hrefURL);
                                    $hrefURL = rtrim($hrefURL,"/");
                                    if(filter_var($hrefURL,FILTER_VALIDATE_URL) == true)
                                    {   
                                        $dump = parse_url($hrefURL);
                                        if(isset($dump["Host"]))
                                        {   $Host = trim(strtolower($dump["Host"]));    }
                                    }
                                    else
                                    {
                                        $hrefURL = $directoryURL."/".$hrefURL;
                                        if(filter_var($hrefURL,FILTER_VALIDATE_URL) == true)
                                        {   
                                            $dump = parse_url($hrefURL);    
                                            if(isset($dump["Host"]))
                                            {   $Host = trim(strtolower($dump["Host"]));    }
                                        }
                                    }
                                    if($Host != "")
                                    {
                                        $extension = pathinfo($hrefURL,PATHINFO_EXTENSION);
                                        if($extension != "")
                                        {
                                            $tempBuffer ="";
                                            $extensionlength = strlen($extension);
                                            for($tempData = 0; $tempData < $extensionlength; $tempData++)
                                            {
                                                if($extension[$tempData] != "?")
                                                {   
                                                    $tempBuffer = $tempBuffer.$extension[$tempData];
                                                    continue;
                                                }
                                                else
                                                {
                                                    $extension = trim($tempBuffer);
                                                    break;
                                                }
                                            }
                                            if(in_array($extension,$Url_Extensions))
                                            {   $type = "domain";   }
                                            else if(in_array($extension,$Image_Extensions))
                                            {   $type = "image";    }
                                            else if(in_array($extension,$Document_Extensions))
                                            {   $type = "document"; }
                                            else
                                            {   $type = "unknown";  }
                                        }
                                        else
                                        {   $type = "domain";   }

                                        if($hrefURL != "")
                                        {
                                            if($type == "domain" && !in_array($hrefURL,$this->linkBuffer["domain"]))
                                            {   $this->linkBuffer["domain"][] = $hrefURL;   }
                                            if($type == "image" && !in_array($hrefURL,$this->linkBuffer["image"]))
                                            {   $this->linkBuffer["image"][] = $hrefURL;    }
                                            if($type == "document" && !in_array($hrefURL,$this->linkBuffer["document"]))
                                            {   $this->linkBuffer["document"][] = $hrefURL; }
                                            if($type == "unknown" && !in_array($hrefURL,$this->linkBuffer["unknown"]))
                                            {   $this->linkBuffer["unknown"][] = $hrefURL;  }
                                        }
                                    }
                                }
                                $hrefTagCountStart = 0;
                            }
                            if($hrefTagCountStart == 3)
                            {
                                $hrefURL = "";
                                $dotCount = 0;
                                $slashCount = 0;
                                $singleSlashCount = 0;
                                $doubleSlashCount = 0;
                                $parentDirectoryCount = 0;
                                $webPageCounter++;
                                while($webPageCounter < $webPageLength)
                                {
                                    $character = $webPageContent[$webPageCounter];
                                    if($character == "")
                                    {   
                                        $webPageCounter++;  
                                        continue;
                                    }
                                    if($character == "\"" || $character == "'")
                                    {
                                        $webPageCounter++;
                                        while($webPageCounter < $webPageLength)
                                        {
                                            $character = $webPageContent[$webPageCounter];
                                            if($character == "")
                                            {   
                                                $webPageCounter++;  
                                                continue;
                                            }
                                            if($character == "\"" || $character == "'" || $character == "#")
                                            {   
                                                $webPageCounter--;  
                                                break;  
                                            }
                                            else if($hrefURL != "")
                                            {   $hrefURL .= $character; }
                                            else if($character == "." || $character == "/")
                                            {
                                                if($character == ".")
                                                {
                                                    $dotCount++;
                                                    $slashCount = 0;
                                                }
                                                else if($character == "/")
                                                {
                                                    $slashCount++;
                                                    if($dotCount == 2 && $slashCount == 1)
                                                    $parentDirectoryCount++;
                                                    else if($dotCount == 0 && $slashCount == 1)
                                                    $singleSlashCount++;
                                                    else if($dotCount == 0 && $slashCount == 2)
                                                    $doubleSlashCount++;
                                                    $dotCount = 0;
                                                }
                                            }
                                            else
                                            {   $hrefURL .= $character; }
                                            $webPageCounter++;
                                        }
                                        break;
                                    }
                                    $webPageCounter++;
                                }
                            }
                            $hrefTagLengthStart = 0;
                            $hrefTagLengthFinal = strlen($hrefTag[$hrefTagCountStart]);
                            $hrefTagPointer =& $hrefTag[$hrefTagCountStart];
                        }
                    }
                    else
                    {   $hrefTagLengthStart = 0;    }
                    //-- Href Filter End --
                    //-- Image Filter Start --
                    if($imgTagPointer[$imgTagLengthStart] == $character)
                    {
                        $imgTagLengthStart++;
                        if($imgTagLengthStart == $imgTagLengthFinal)
                        {
                            $imgTagCountStart++;
                            if($imgTagCountStart == $imgTagCountFinal)
                            {
                                if($imgURL != "")
                                {
                                    if($parentDirectoryCount >= 1 || $singleSlashCount >= 1 || $doubleSlashCount >= 1)
                                    {
                                        if($doubleSlashCount >= 1)
                                        {   $imgURL = "http://".$imgURL;    }
                                        else if($parentDirectoryCount >= 1)
                                        {
                                            $tempData = 0;
                                            $tempString = "";
                                            $tempTotal = count($urlParser) - $parentDirectoryCount;
                                            while($tempData < $tempTotal)
                                            {
                                                $tempString .= $urlParser[$tempData]."/";
                                                $tempData++;
                                            }
                                            $imgURL = $tempString."".$imgURL;
                                        }
                                        else if($singleSlashCount >= 1)
                                        {   $imgURL = $urlParser[0]."/".$urlParser[1]."/".$urlParser[2]."/".$imgURL;    }
                                    }
                                    $Host = "";
                                    $imgURL = urldecode($imgURL);
                                    $imgURL = rtrim($imgURL,"/");
                                    if(filter_var($imgURL,FILTER_VALIDATE_URL) == true)
                                    {   
                                        $dump = parse_url($imgURL); 
                                        $Host = trim(strtolower($dump["Host"]));
                                    }
                                    else
                                    {
                                        $imgURL = $directoryURL."/".$imgURL;
                                        if(filter_var($imgURL,FILTER_VALIDATE_URL) == true)
                                        {   
                                            $dump = parse_url($imgURL); 
                                            $Host = trim(strtolower($dump["Host"]));
                                        }   
                                    }
                                    if($Host != "")
                                    {
                                        $extension = pathinfo($imgURL,PATHINFO_EXTENSION);
                                        if($extension != "")
                                        {
                                            $tempBuffer ="";
                                            $extensionlength = strlen($extension);
                                            for($tempData = 0; $tempData < $extensionlength; $tempData++)
                                            {
                                                if($extension[$tempData] != "?")
                                                {   
                                                    $tempBuffer = $tempBuffer.$extension[$tempData];
                                                    continue;
                                                }
                                                else
                                                {
                                                    $extension = trim($tempBuffer);
                                                    break;
                                                }
                                            }
                                            if(in_array($extension,$Url_Extensions))
                                            {   $type = "domain";   }
                                            else if(in_array($extension,$Image_Extensions))
                                            {   $type = "image";    }
                                            else if(in_array($extension,$Document_Extensions))
                                            {   $type = "document"; }
                                            else
                                            {   $type = "unknown";  }
                                        }
                                        else
                                        {   $type = "domain";   }

                                        if($imgURL != "")
                                        {
                                            if($type == "domain" && !in_array($imgURL,$this->linkBuffer["domain"]))
                                            {   $this->linkBuffer["domain"][] = $imgURL;    }
                                            if($type == "image" && !in_array($imgURL,$this->linkBuffer["image"]))
                                            {   $this->linkBuffer["image"][] = $imgURL; }
                                            if($type == "document" && !in_array($imgURL,$this->linkBuffer["document"]))
                                            {   $this->linkBuffer["document"][] = $imgURL;  }
                                            if($type == "unknown" && !in_array($imgURL,$this->linkBuffer["unknown"]))
                                            {   $this->linkBuffer["unknown"][] = $imgURL;   }
                                        }
                                    }
                                }
                                $imgTagCountStart = 0;
                            }
                            if($imgTagCountStart == 3)
                            {
                                $imgURL = "";
                                $dotCount = 0;
                                $slashCount = 0;
                                $singleSlashCount = 0;
                                $doubleSlashCount = 0;
                                $parentDirectoryCount = 0;
                                $webPageCounter++;
                                while($webPageCounter < $webPageLength)
                                {
                                    $character = $webPageContent[$webPageCounter];
                                    if($character == "")
                                    {   
                                        $webPageCounter++;  
                                        continue;
                                    }
                                    if($character == "\"" || $character == "'")
                                    {
                                        $webPageCounter++;
                                        while($webPageCounter < $webPageLength)
                                        {
                                            $character = $webPageContent[$webPageCounter];
                                            if($character == "")
                                            {   
                                                $webPageCounter++;  
                                                continue;
                                            }
                                            if($character == "\"" || $character == "'" || $character == "#")
                                            {   
                                                $webPageCounter--;  
                                                break;  
                                            }
                                            else if($imgURL != "")
                                            {   $imgURL .= $character;  }
                                            else if($character == "." || $character == "/")
                                            {
                                                if($character == ".")
                                                {
                                                    $dotCount++;
                                                    $slashCount = 0;
                                                }
                                                else if($character == "/")
                                                {
                                                    $slashCount++;
                                                    if($dotCount == 2 && $slashCount == 1)
                                                    $parentDirectoryCount++;
                                                    else if($dotCount == 0 && $slashCount == 1)
                                                    $singleSlashCount++;
                                                    else if($dotCount == 0 && $slashCount == 2)
                                                    $doubleSlashCount++;
                                                    $dotCount = 0;
                                                }
                                            }
                                            else
                                            {   $imgURL .= $character;  }
                                            $webPageCounter++;
                                        }
                                        break;
                                    }
                                    $webPageCounter++;
                                }
                            }
                            $imgTagLengthStart = 0;
                            $imgTagLengthFinal = strlen($imgTag[$imgTagCountStart]);
                            $imgTagPointer =& $imgTag[$imgTagCountStart];
                        }
                    }
                    else
                    {   $imgTagLengthStart = 0; }
                    //-- Image Filter End --
                    $webPageCounter++;
                }
            }
            else
            {   $this->error = "Unable to proceed, permission denied";  }
        }
        else
        {   $this->error = "Please enter url";  }

        if($this->error != "")
        {   $this->linkBuffer["error"] = $this->error;  }

        return $this->linkBuffer;
    }   
}
?>
0