Más honlap(ok) bizonyos részének átvétele

blogA 108.hu-ra kelett egy modult készítenem, amely összegyűjti a bhakta blogok legfrisebb bejegyzéseit. Ilyesmit csinál a blogroll, vagy a hírekkel a hírkereső. Többféle megoldást is kipróbáltam, melyekből ez bizonyult a leghasználhatóbbnak. Az eljárás egyszerű, de nagyszerű.Előszőr azzal próbálkoztam, hogy amikor a user megnyitja az oldalt, akkor egy sima fopen szépen végignyitogatja a vizsgálandó oldalakat és beolvassa ezekről a szükséges (mondjuk a legfrisebb) adatokat. Ezzel az volt a baj, hogy már 3 különböző oldalnál az oldal letöltését drasztikusan lecsökkentette. Megnéztem különböző variációkat ezen az alapon (fsockopen, fopen, curl, join(file), file_get_contents) de így mind lassú volt. Ekkor úgy gondoltam, hogy el lehetne menteni egy állapotot egy szövegfileba, amit aztán bizonyos időközönként (pl 2 óránként) lehetne frissíteni.

Ehhez a következő 3 alkotóelemet kellett összerakni:

  1. írni egy függvényt, ami végiglátogatja az oldalakat, kiveszi belőlük az áhított tartalmat és beleírja egy szövegfileba
  2. létrehozni egy cron feladatot ami a fenti scriptet lefuttatja bizonyos időközönként
  3. írni egy másik függvényt ami a szövegfileból beolvassa az adatokat és megjeleníti az oldalon

Az oldallátogató függvény

#!/usr/local/bin/php

<?php

function frissblog($webcim,$cim,$keres,$cserelminta,
  $tobbsor=false){
/*
A megadott $webcimmel kapcsolatba lép
megkeresi a $keres kifejezést, ha ebben a sorban nincs link
  akkor hozzáadja, a $cserelminta mintára illeszkedő részt
  kiveszi a sorból, a $tobbsor true esetén ezt több mint egy
  soron keresztül folytatja
*/
  $kimenet .= "nt".'<li>';
  $fp = fopen("http://".$webcim."/", "r");
  if (!$fp){
    $kimenet .= $webcim . ' (nem elérhető)';
    }
  else{
    $kilep = $megvan = false;
    while(!feof($fp) && !$kilep){
      /*keressük meg az első bejegyzést (sort)
         ami illik $keres mintára*/
      if(strpos($sor=fgets($fp),$keres) !== false || $megvan){
	  //ha van linkje távolítsuk el az esetleg ott megbúvó
           stílus definíciót, style vagy class
        $sor = preg_replace("/style="[^"]*"/",'',$sor);
        $sor = preg_replace("/class="[^"]*"/",'',$sor);
		
		//ha több soron keresztül kerestünk és elértük a végét
        if($tobbsor && $megvan){
          $kimenet .= preg_replace("/$cserelminta/",'',$sor);
          $kilep = true;
          }
        //többsoros, de még nem értük el a végét
        elseif($tobbsor){
          $kimenet .= preg_replace("/$cserelminta/",'',$sor);
          }
        //nem többsoros
        elseif(!$tobbsor){
          $kimenet .= preg_replace("/$cserelminta/",'',$sor);
          $kilep = true;
          }
		  
		  $megvan = true;
        }
         }
		 //ha nincs benne link adjuk hozzá
    if(strpos($kimenet,'<a href') === false)
      $kimenet = '<a href="http://'.$webcim.'">' . $kimenet .
        '</a>';
		$kimenet .= ' <span class="blogcim">('.$cim.')
      </span></li>';
	  //gyomláljuk ki az esetleg bekerült  -ket
    $kimenet = str_replace(' ','',$kimenet);
	fclose($fp);
    }
  return($kimenet);
  }
//---------------------------------------------------------

$kimenet .= '<ul>';
$kimenet .= frissblog('krisnamosolya.blogter.hu','Krisna
     mosolya','<h1>','</*h1[^>]*>');
	$kimenet .= frissblog('lal.freeblog.hu','Egy krisnás szerzetes
    naplója','<div class="bejegyzescim">','</*[^>]*>',true);
	$kimenet .= '</ul>';
	$fp = fopen(ALAPKONYVTAR.'moduls/blog.txt','w');
fwrite($fp,$kimenet . "n");
fclose($fp);
?>

Az első sor #!/usr/local/bin/php tudja a parserrel, hogy a kis php programunk nem normál böngészőn keresztül futtatott program, hanem egy parancssori program. Ezt a formátumot kell használnunk ha olyan php programokat írunk, amelyeket parancssorból akarunk futtatni. Az elérési út a php futtatható állományára kell mutasson.

A függvényünk fopen-nel megnyitja a kért webcímet és az ott talált filet (ami várhatóan az index.php vagy index.html) elkezdi soronként végignézni. Ha megtalálja benne a keresett mintát akkor azt tisztítja, szükség esetén hozzáadja a linket, hozzáadja a hivatkozó szöveget és az így összerakott stringet adja vissza visszatérési értékként.

Ezután a különböző blogokra meghívjuk a függvényt a megfelelő paraméterekkel. A mintákat úgy találtam ki, hogy ellátogattam az oldalakra és a forrásfileban megnéztem, hogy hogy néznek ki a legfrisebb bejegyzések.
Végül pedig fwrite-tal beleírjuk az egészet a szövegfileunkba. Ezt a filet jó előtte a php számára írhatóvá tenni, és a jogait futtathatóra állítani, máskülönben egyrészt nem fog működni, másrészt meg eltöltünk egy csomó időt azzal, hogy megpróbáljuk kitalálni, hogy miért nem. Ha feltesszük a programocskát a szerverre és meghívjuk a kedvenc böngészőnkkel, akkor az első sort fogja kiírni csupán. Ha ezen felül még kiír valamit akkor nézegessük meg mert nagy eséllyel hibaüzenetek lesznek. A betöltendő oldalak számától függően akár 1-2 percig is eltarthat míg lefut.

A cron

A cron démon a linux rendszerek egyik alapvető eleme, hacsak valami érthetelen oknál fogva nem Windows fut a webszerverünkön, akkor biztosan ott lesz a démonok között. A probléma annyi, hogy általában sima felhasználóknak nincs joga egy webszerveren cron feladatokat létrehozni, de gondolom a szolgáltatók nagy részének nincs különösebb kifogása egy ilyen aranyos kis cron task futtatása ellen.

Előszőr létre kell hoznunk egy szövegfilet, ami az alábbi formátumban kell legyen:

10 */2 * * * /home/rrd/public_html/108/blog.php

Az első szám azt jelzi, hogy a parancsot melyik percben, a második, hogy melyik órában, aztán melyik napon, melyik hónapban, és a hét melyik napján kell lefuttatni. Ha valamelyik szám helyén * van akkor azt jelenti, hogy minden. Azaz a mi esetünkben minden második órában az óra 10. percében kell lefuttatnia a fenti elérési úton lévő blog.php filet. Tovább nem magyarázom, akit érdekel az keressen rá a crontab-ra, magyarul is sok leírás található.

Ha esetleg adminisztrációs hozzáférésünk van a szerverhez, akkor lehet, hogy az adminisztrációs programunkban van olyan rész ahol crontab taskokat lehet kezelni. A DirectAdmin például ilyen. Ha nincs akkor valahogy rá kell vennünk a webszerver üzemeltetőjét, hogy életet leheljen a crontab fileunkba. Ha van ssh hozzáférésünk akkor meg mi magunk is meg tudjuk csinálni.

A megjelenítő függvény

if($_SESSION['blog']) print $_SESSION['blog'];
else{
  $fp = @fopen("./moduls/blog.txt", "r");
  if (!$fp){
    print 'Nem elérhető';
    }
  else{
    while(!feof($fp)){
      $kimenet .= fgets($fp);
      }
    fclose($fp);
    }
  $_SESSION['blog'] = $kimenet;
  print $_SESSION['blog'];
  }

Semmi érdekes. Megvizsgálom, hogy létezik-e már a sessionben a blog bejegyzés, ha nem akkor beolvasom a blog.php által generált fileból. Ez azért kell mert elvileg a sessionban szereplő adatokhoz gyorsabban hozzáfér a php mint ha minden oldalletöltésnél a filet kellene nyitogálnia. Ezután meg fogjuk és egyszerűen kiírjuk a sessionból a tartalmat.

Ennyi az egész és kész!

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöljük.