Building a PHP Web Crawler from Scratch

A web crawler, also known as a web spider, is an automated program or script that systematically navigates through websites on the Internet to gather information. Web crawlers start by visiting a seed URL and then follow hyperlinks to other pages, recursively exploring and indexing the content they find.The primary purpose of a web crawler is to gather data from web pages, such as text, images, links, metadata, and other relevant information. This collected data is typically used for various purposes, including web indexing, data mining, content scraping, and search engine optimization. Web crawlers work by sending HTTP requests to web servers, downloading web pages, parsing the HTML or other structured data, and extracting relevant information. They follow the links found on each page to discover new URLs to crawl, creating a vast network of interconnected web pages.

You can get the complete code from Github

index.php
1 <?php
2 include_once("config.php");
3 include_once("WebCrawler.php");
4 
5 $obj = new WebCrawler();
6 $data = $obj->parser("https://www.algoberry.com");
7 echo "<pre>";
8 print_r($data);
9 echo "</pre>";
10 ?>
config.php
1 <?php
2 //--
3 $outerHead = "<head>";
4 $outerHeadLength = strlen($outerHead);
5 $outerHeadStart = 0;
6 
7 $innerHead = "</head>";
8 $innerHeadLength = strlen($innerHead);
9 $innerHeadStart = 0;
10 //--
11 
12 //--
13 $outerTitle = "<title>";
14 $outerTitleLength = strlen($outerTitle);
15 $outerTitleStart = 0;
16 
17 $innerTitle = "</title>";
18 $innerTitleLength = strlen($innerTitle);
19 $innerTitleStart = 0;
20 //--
21 
22 //--
23 $outerMeta = "<meta";
24 $innerMeta = ">";
25 $metaPointer = 0;
26 //--
27 
28 //--
29 $metaNameBase = "name=";
30 $metaNamePointer = 0;
31 //--
32 
33 //--
34 $metaPropertyBase = "property=";
35 $metaPropertyPointer = 0;
36 //--
37 
38 //--
39 $metaContentBase = "content=";
40 $metaContentPointer = 0;
41 //--
42 
43 //--
44 $hrefTag = array();
45 $hrefTag[0] = "<a";
46 $hrefTag[1] = "href";
47 $hrefTag[2] = "=";
48 $hrefTag[3] = ">";
49 $hrefTagCountStart = 0;
50 $hrefTagCountFinal = count($hrefTag);
51 $hrefTagLengthStart = 0;
52 $hrefTagLengthFinal = strlen($hrefTag[0]);
53 $hrefTagPointer =& $hrefTag[0];
54 //--
55 
56 //--
57 $imgTag = array();
58 $imgTag[0] = "<img";
59 $imgTag[1] = "src";
60 $imgTag[2] = "=";
61 $imgTag[3] = ">";
62 $imgTagCountStart = 0;
63 $imgTagCountFinal = count($imgTag);
64 $imgTagLengthStart = 0;
65 $imgTagLengthFinal = strlen($imgTag[0]);
66 $imgTagPointer =& $imgTag[0];
67 //--
68 
69 //--
70 $crawlOptions = array(
71 CURLOPT_RETURNTRANSFER => true,     		// return web page
72 CURLOPT_HEADER         => false,    		// don't return headers
73 CURLOPT_FOLLOWLOCATION => true,     		// follow redirects
74 CURLOPT_ENCODING       => "",       		// handle all encodings
75 CURLOPT_USERAGENT      => "algoberrybot", 	// who am i
76 CURLOPT_AUTOREFERER    => true,     		// set referer on redirect
77 CURLOPT_CONNECTTIMEOUT => 10,      			// timeout on connect
78 CURLOPT_TIMEOUT        => 10,      			// timeout on response
79 CURLOPT_MAXREDIRS      => 0       			// stop after 10 redirects
80 );
81 //--
82 ?>
WebCrawler.php
1 <?php
2 Class WebCrawler {
3 
4     public $webPageContent;
5 
6     function parser($directoryURL) {
7         $result = array();
8         global $outerHead, $outerHeadLength, $outerHeadStart;
9         global $innerHead, $innerHeadLength, $innerHeadStart;
10         global $outerTitle, $outerTitleLength, $outerTitleStart;
11         global $innerTitle, $innerTitleLength, $innerTitleStart;
12 
13         global $outerMeta, $innerMeta, $metaPointer;
14         global $metaNameBase, $metaNamePointer;
15         global $metaPropertyBase, $metaPropertyPointer;
16         global $metaContentBase, $metaContentPointer;
17 
18         global $hrefTag, $hrefTagCountStart, $hrefTagCountFinal, $hrefTagLengthStart, $hrefTagLengthFinal, $hrefTagPointer;
19         global $imgTag, $imgTagCountStart, $imgTagCountFinal, $imgTagLengthStart, $imgTagLengthFinal, $imgTagPointer;
20         global $crawlOptions;
21 
22         if($directoryURL != "") {
23             if(filter_var$directoryURL,FILTER_VALIDATE_URL == true) {
24                 $hrefURL = "";
25                 $imgURL = "";
26                 $previousDirectoryCount = 0;
27                 $currentDirectoryCount = 0;
28                 $singleSlashCount = 0;
29                 $doubleSlashCount = 0;
30 
31                 $urlParser = preg_split("/\//",$directoryURL);
32                 $dump = parse_url($directoryURL);
33                 $ownHost = $dump["host"]; 
34 
35                 $curlObject = curl_init($directoryURL);
36                 curl_setopt_array($curlObject,$crawlOptions);
37                 $this->webPageContent = curl_exec($curlObject);
38                 $errorNumber = curl_errno($curlObject);
39                 curl_close($curlObject);
40 
41                 if($errorNumber == 0) {
42                     //--
43                     $counter = 0;
44                     $contentLength = strlen($this->webPageContent);
45                     while($counter < $contentLength) {
46                         $character = $this->webPageContent[$counter];
47                         if($character == " ") {	
48                             $counter++;	
49                             continue;
50                         }
51                         if($outerHead[$outerHeadStart] == $character) {
52                             $outerHeadStart++;
53                             if($outerHeadStart == $outerHeadLength) {
54                                 $outerHeadStart = 0;
55                                 $counter++;
56                                 while($counter < $contentLength) {
57                                     $character = $this->webPageContent[$counter];
58                                     if($character == " ") {	
59                                         $counter++;	
60                                         continue;
61                                     }
62                                     //--
63                                     if($outerTitle[$outerTitleStart] == $character) {
64                                         $outerTitleStart++;
65                                         if($outerTitleStart == $outerTitleLength) {
66                                             $outerTitleStart = 0;
67                                             $counter++;
68                                             $startPosition = $counter;
69                                             while($counter < $contentLength) {
70                                                 $character = $this->webPageContent[$counter];
71                                                 if($character == " ") {	
72                                                     $counter++;	
73                                                     continue;
74                                                 }
75                                                 if($innerTitle[$innerTitleStart] == $character) {
76                                                     if($innerTitleStart == 0) {
77                                                         $endPosition = $counter - 1;
78                                                     }
79                                                     $innerTitleStart++;
80                                                     if($innerTitleStart == $innerTitleLength) {
81                                                         $innerTitleStart = 0;
82                                                         $result["title"] = $this->collectData($startPosition,$endPosition);
83                                                         break;
84                                                     }
85                                                 }
86                                                 else
87                                                 {
88                                                     $innerTitleStart = 0;
89                                                 }
90                                                 $counter++;
91                                             }
92                                         }
93                                     }
94                                     else
95                                     {
96                                         $outerTitleStart = 0;
97                                     }
98                                     //--
99                                     //--
100                                     if($outerMeta[$metaPointer] == $character) {
101                                         $metaPointer++;
102                                         if($metaPointer == strlen$outerMeta) {
103                                             $metaPointer = 0;
104                                             $startPosition = 0;
105                                             $endPosition = 0;
106                                             $metaType = "";
107                                             $metaValue = "";
108                                             $counter++;
109                                             while($counter < $contentLength) {
110                                                 $character = $this->webPageContent[$counter];
111                                                 if($character == " ") {	
112                                                     $counter++;	
113                                                     continue;
114                                                 }
115                                                 if($metaNameBase[$metaNamePointer] == $character) {
116                                                     $metaNamePointer++;
117                                                     if($metaNamePointer == strlen$metaNameBase) {
118                                                         $metaNamePointer = 0;
119                                                         $counter++;
120                                                         while($counter < $contentLength) {
121                                                             $character = $this->webPageContent[$counter];
122                                                             if($character == "\"" || $character == "'") {
123                                                                 if($startPosition == 0) {
124                                                                     $startPosition = $counter + 1;
125                                                                 }
126                                                                 else if($endPosition == 0) {
127                                                                     $endPosition = $counter - 1;
128                                                                     break;
129                                                                 }
130                                                             }
131                                                             $counter++;
132                                                         }
133                                                         $metaType = $this->collectData($startPosition,$endPosition);
134                                                         $startPosition = 0;
135                                                         $endPosition = 0;
136                                                     }
137                                                 }
138                                                 else
139                                                 {
140                                                     $metaNamePointer = 0;
141                                                 }
142                                                 if($metaPropertyBase[$metaPropertyPointer] == $character) {
143                                                     $metaPropertyPointer++;
144                                                     if($metaPropertyPointer == strlen$metaPropertyBase) {
145                                                         $metaPropertyPointer = 0;
146                                                         $counter++;
147                                                         while($counter < $contentLength) {
148                                                             $character = $this->webPageContent[$counter];
149                                                             if($character == "\"" || $character == "'") {
150                                                                 if($startPosition == 0) {
151                                                                     $startPosition = $counter + 1;
152                                                                 }
153                                                                 else if($endPosition == 0) {
154                                                                     $endPosition = $counter - 1;
155                                                                     break;
156                                                                 }
157                                                             }
158                                                             $counter++;
159                                                         }
160                                                         $metaType = $this->collectData($startPosition,$endPosition);
161                                                         $startPosition = 0;
162                                                         $endPosition = 0;
163                                                     }
164                                                 }
165                                                 else
166                                                 {
167                                                     $metaPropertyPointer = 0;
168                                                 }
169                                                 if($metaContentBase[$metaContentPointer] == $character) {
170                                                     $metaContentPointer++;
171                                                     if($metaContentPointer == strlen$metaContentBase) {
172                                                         $metaContentPointer = 0;
173                                                         $counter++;
174                                                         while($counter < $contentLength) {
175                                                             $character = $this->webPageContent[$counter];
176                                                             if($character == "\"" || $character == "'") {
177                                                                 if($startPosition == 0) {
178                                                                     $startPosition = $counter + 1;
179                                                                 }
180                                                                 else if($endPosition == 0) {
181                                                                     $endPosition = $counter - 1;
182                                                                     break;
183                                                                 }
184                                                             }
185                                                             $counter++;
186                                                         }
187                                                         $metaValue = $this->collectData($startPosition,$endPosition);
188                                                         $startPosition = 0;
189                                                         $endPosition = 0;
190                                                     }
191                                                 }
192                                                 else
193                                                 {
194                                                     $metaContentPointer = 0;
195                                                 }
196                                                 if($innerMeta == $character) {
197                                                     if($metaType != "" && $metaValue != "") {
198                                                         $result["meta"][$metaType] = $metaValue;
199                                                     }
200                                                     break;
201                                                 }
202                                                 $counter++;
203                                             }
204                                         }
205                                     }
206                                     else
207                                     {
208                                         $metaPointer = 0;
209                                     }
210                                     //--
211                                     //--
212                                     if($innerHead[$innerHeadStart] == $character) {
213                                         $innerHeadStart++;
214                                         if($innerHeadStart == $innerHeadLength) {
215                                             $innerHeadStart = 0;
216                                             break;
217                                         }
218                                     }
219                                     else
220                                     {
221                                         $innerHeadStart = 0;
222                                     }
223                                     //--
224                                     $counter++;
225                                 }
226                                 break;
227                             }
228                         }
229                         else
230                         {
231                             $outerHeadStart = 0;
232                         }
233                         $counter++;
234                     }
235                     //--
236                     
237                     //--
238                     $counter++;
239                     while($counter < $contentLength) {
240                         $character = $this->webPageContent[$counter];
241                         if($character == "") {
242                             $counter++;	
243                             continue;
244                         }
245                         if($hrefTagPointer[$hrefTagLengthStart] == $character) {
246                             $hrefTagLengthStart++;
247                             if($hrefTagLengthStart == $hrefTagLengthFinal) {
248                                 $hrefTagCountStart++;
249                                 if($hrefTagCountStart == $hrefTagCountFinal) {
250                                     $hrefTagCountStart = 0;
251                                     if($previousDirectoryCount > 0 || $currentDirectoryCount > 0 || $singleSlashCount > 0 || $doubleSlashCount > 0) {
252                                         if($previousDirectoryCount > 0) {
253                                             $tempString = "";
254                                             $tempCount = 0;
255                                             $tempTotal = count($urlParser) - $previousDirectoryCount;
256                                             while($tempCount < $tempTotal) {
257                                                 $tempString .= $urlParser[$tempCount]."/";
258                                                 $tempCount++;
259                                             }
260                                             $hrefURL = $tempString.$hrefURL;
261                                         }
262                                         else if($currentDirectoryCount > 0) {
263                                             $hrefURL = $directoryURL."/".$hrefURL;
264                                         }
265                                         else if($singleSlashCount > 0) {
266                                             $hrefURL = $directoryURL."/".$hrefURL;
267                                         }
268                                         else if($doubleSlashCount > 0) {
269                                             $hrefURL = $urlParser[0]."//".$hrefURL;
270                                         }
271                                     }
272                                     if(filter_var$hrefURL,FILTER_VALIDATE_URL == true) {
273                                         $dump = parse_url($hrefURL);
274                                         if($ownHost == $dump["host"]) {
275                                             $result["href"]["own"][] = $hrefURL;
276                                         }
277                                         else
278                                         {
279                                             $result["href"]["other"][] = $hrefURL;
280                                         }
281                                     }
282                                 }
283                                 else if($hrefTagCountStart == 3) {
284                                     //--
285                                     $hrefURL = "";
286                                     $previousDirectoryCount = 0;
287                                     $currentDirectoryCount = 0;
288                                     $singleSlashCount = 0;
289                                     $doubleSlashCount = 0;
290                                     //--
291                     
292                                     $dotCount = 0;
293                                     $slashCount = 0;
294                     
295                                     $firstCharacter = "";
296                                     $leftPosition = 0;
297                                     $rightPosition = 0;
298                                     
299                                     $counter++;
300                                     while($counter < $contentLength) {
301                                         $character = $this->webPageContent[$counter];
302                                         if($character == "\"" || $character == "'") {
303                                             if($firstCharacter == "") {
304                                                 $firstCharacter = $character;
305                                                 $leftPosition = $counter + 1;
306                                             }
307                                             else if($firstCharacter == $character) {
308                                                 $rightPosition = $counter - 1;
309                                                 break;
310                                             }
311                                         }
312                                         else if($character == "#") {
313                                             $hrefTagCountStart = 0;
314                                             break;
315                                         }
316                                         $counter++;
317                                     }
318                                     while($leftPosition <= $rightPosition) {
319                                         $character = $this->webPageContent[$leftPosition];
320                                         if($hrefURL != "") {
321                                             $hrefURL .= $character;
322                                         }
323                                         else if($character == "." || $character == "/") {
324                                             if($character == ".") {
325                                                 $dotCount++;
326                                                 $slashCount = 0;
327                                             }
328                                             else if($character == "/") {
329                                                 $slashCount++;
330                                                 if($dotCount == 2 && $slashCount == 1) {
331                                                     $previousDirectoryCount++;
332                                                 }
333                                                 else if($dotCount == 1 && $slashCount == 1) {
334                                                     $currentDirectoryCount++;
335                                                 }
336                                                 else if($dotCount == 0 && $slashCount == 1) {
337                                                     $singleSlashCount++;
338                                                 }
339                                                 else if($dotCount == 0 && $slashCount == 2) {
340                                                     $singleSlashCount = 0;
341                                                     $doubleSlashCount++;
342                                                 }
343                                             }
344                                         }
345                                         else
346                                         {
347                                             $hrefURL .= $character;
348                                         }
349                                         $leftPosition++;
350                                     }
351                                 }
352                                 $hrefTagLengthStart = 0;
353                                 $hrefTagLengthFinal = strlen($hrefTag[$hrefTagCountStart]);
354                                 $hrefTagPointer =& $hrefTag[$hrefTagCountStart];
355                             }
356                         }
357                         else
358                         {
359                             $hrefTagLengthStart = 0;
360                         }
361                         if($imgTagPointer[$imgTagLengthStart] == $character) {
362                             $imgTagLengthStart++;
363                             if($imgTagLengthStart == $imgTagLengthFinal) {
364                                 $imgTagCountStart++;
365                                 if($imgTagCountStart == $imgTagCountFinal) {
366                                     $imgTagCountStart = 0;
367                                     if($previousDirectoryCount > 0 || $currentDirectoryCount > 0 || $singleSlashCount > 0 || $doubleSlashCount > 0) {
368                                         if($previousDirectoryCount > 0) {
369                                             $tempString = "";
370                                             $tempCount = 0;
371                                             $tempTotal = count($urlParser) - $previousDirectoryCount;
372                                             while($tempCount < $tempTotal) {
373                                                 $tempString .= $urlParser[$tempCount]."/";
374                                                 $tempCount++;
375                                             }
376                                             $hrefURL = $tempString.$hrefURL;
377                                         }
378                                         else if($currentDirectoryCount > 0) {
379                                             $hrefURL = $directoryURL."/".$hrefURL;
380                                         }
381                                         else if($singleSlashCount > 0) {
382                                             $hrefURL = $directoryURL."/".$hrefURL;
383                                         }
384                                         else if($doubleSlashCount > 0) {
385                                             $hrefURL = $urlParser[0]."//".$hrefURL;
386                                         }
387                                     }
388                                     if(filter_var$hrefURL,FILTER_VALIDATE_URL == true) {
389                                         $result["img"][] = $hrefURL;
390                                     }
391                                 }
392                                 else if($imgTagCountStart == 3) {
393                                     //--
394                                     $hrefURL = "";
395                                     $previousDirectoryCount = 0;
396                                     $currentDirectoryCount = 0;
397                                     $singleSlashCount = 0;
398                                     $doubleSlashCount = 0;
399                                     //--
400                     
401                                     $dotCount = 0;
402                                     $slashCount = 0;
403                     
404                                     $firstCharacter = "";
405                                     $leftPosition = 0;
406                                     $rightPosition = 0;
407                                     
408                                     $counter++;
409                                     while($counter < $contentLength) {
410                                         $character = $this->webPageContent[$counter];
411                                         if($character == "\"" || $character == "'") {
412                                             if($firstCharacter == "") {
413                                                 $firstCharacter = $character;
414                                                 $leftPosition = $counter + 1;
415                                             }
416                                             else if($firstCharacter == $character) {
417                                                 $rightPosition = $counter - 1;
418                                                 break;
419                                             }
420                                         }
421                                         else if($character == "#") {
422                                             $imgTagCountStart = 0;
423                                             break;
424                                         }
425                                         $counter++;
426                                     }
427                                     while($leftPosition <= $rightPosition) {
428                                         $character = $this->webPageContent[$leftPosition];
429                                         if($hrefURL != "") {
430                                             $hrefURL .= $character;
431                                         }
432                                         else if($character == "." || $character == "/") {
433                                             if($character == ".") {
434                                                 $dotCount++;
435                                                 $slashCount = 0;
436                                             }
437                                             else if($character == "/") {
438                                                 $slashCount++;
439                                                 if($dotCount == 2 && $slashCount == 1) {
440                                                     $previousDirectoryCount++;
441                                                 }
442                                                 else if($dotCount == 1 && $slashCount == 1) {
443                                                     $currentDirectoryCount++;
444                                                 }
445                                                 else if($dotCount == 0 && $slashCount == 1) {
446                                                     $singleSlashCount++;
447                                                 }
448                                                 else if($dotCount == 0 && $slashCount == 2) {
449                                                     $singleSlashCount = 0;
450                                                     $doubleSlashCount++;
451                                                 }
452                                             }
453                                         }
454                                         else
455                                         {
456                                             $hrefURL .= $character;
457                                         }
458                                         $leftPosition++;
459                                     }
460                                 }
461                                 $imgTagLengthStart = 0;
462                                 $imgTagLengthFinal = strlen($imgTag[$imgTagCountStart]);
463                                 $imgTagPointer =& $imgTag[$imgTagCountStart];
464                             }
465                         }
466                         else
467                         {
468                             $imgTagLengthStart = 0;
469                         }
470                         $counter++;
471                     }
472                    //--
473                 }
474             }
475         }
476         return $result;
477     }
478     
479     function collectData($start, $end) {
480         $temp = "";
481         while($start <= $end) {
482             $temp .= $this->webPageContent[$start];
483             $start++;
484         }
485         return $temp;
486     }
487 }
488 ?>

No comments:

Post a Comment