Kategória: szkript

Avagy hogyan migráltam a webni.innen.hu tartalmát erre a WordPress oldalra? Ebben a bejegyzésben a költöztetés első lépéséről olvashatsz: milyen, nem teljesen erre a feladatra kitalált technológiával exportáltam a régi oldalam tartalmait.

A webni.innen.hu költöztetése című bejegyzésben már nagyvonalakban leírtam a folyamatot, most egy jóval részletesebben mutatom be az első lépéseket. Ez a tapasztalatok azoknak lehetnek érdekesek, akik komplexebb weboldalak tartalmait szeretnék maguk is költöztetni.

Első lépés: a Zwiki-vel készült szájt szkrépelése

Strukturált tartalom előállítása

Egy webszájt költöztetésének első lépése, hogy a megszüntetésre ítélt szájton fent lévő tartalmat valamilyen strukturált formába öntsük. Mivel hogy esetünkben egy Zwiki tartalomkezelő rendszerrel készült szájtról beszélünk, a strukturált szón különös hangsúly van. A Wiki jellegű weboldalak egyik fő ismérve, hogy igen gyakran egy adott weblapon megjelenített összes tartalom egyetlen mezőben játszik: a Zwiki esetében például ugyanabban a sima szöveges mezőben kapott helyet az oldal tulajdonképpeni tartalma és az összes, az oldalhoz szó szerint hozzáfűzött komment. A rendszer pedig ebből az ömlesztett szövegből egy egyszerű speciális szövegformázási megoldás értelmezésével ismerte fel, hogy melyek a hozzászólások, és melyik az oldal szövegtörzse. Emiatt az oldal tartalmának strukturált letöltése során az én szkriptemnek is meg kellett találnia ezeket a jellegzetességeket, hogy külön el tudjam raktározni a szövegtörzset és az egyes hozzászólásokat.

Speciális markup formázás kezelése

További kihívás volt, hogy a Zwiki, a többi wiki rendszerrel egyetemben, egy speciális, a HTML-nél jóval egyszerűbb formázási nyelvet használ, amit egy mai tartalomkezelő rendszer nem ismer fel. Pl. a fejezetcímet és annak szintjét úgy lehetett renkívül egyszerűen meghatározni, hogy hány szóköz szerepelt egy sortörés után következő sor elején. Emiatt a szerkesztőfelületen a szerkesztőmezőből kinyert szöveggel nem sokat tudtam volna kezdeni, így a publikus felületről kellett leszedni a már HTML formátumban renderelt tartalmakat.

Letöltés emberi látogatók imitálásával

Mivel alaposan ismerek és használok egy pár web scraper / web automatizáló eszközt, ezért a költöztetésnél is erre – az eredendően az emberi látogatók imitálására épülő –technológiára esett a választásom. Mintha egy átlagos látogató végigkattintaná az összes elérhető weblapot, és lementené a saját meghajtójára. Ezzel a módszerrel nem kötött az, hogy milyen export formátumokat kínál fel a régi oldal (semmilyet), és milyen import formátumokat tesz elérhetővé az új CMS. Ezekkel az online marketing programozás-ról szóló bejegyzésemben is említett rendszerekkel bármelyik részét meg tudom szerezni egy weboldalnak, bármilyen reguláris kifejezéssel fel tudom dolgozni, továbbá tetszőleges formátumban le tudom menteni.

A letöltő (szkréper) szkript logikája

A Wiki alapú tartalomkezelő rendszereknek van egy jó tulajdonsága, ami nagyban megkönnyíti az általuk kezelt oldal összes tartalmának megtalálását: szinte mindegyiküknél van ugyanis egy tartalomjegyzék-szerű weblap, ahol az összes wikilap ki van listázva. Emiatt a letöltő szkriptnek nagyon egyszerű logikája lehetett: kinyitni a tartalomjegyzék-oldalt, leszedni az összes ottani linket, majd egyenként végigmenve a linkek listáján, megnyitni az összes lapot, megtalálni a html kódban a címet, a szülőoldalakat, a szövegtörzset és a hozzászólásokat, majd átkattintani változtatástörténet aloldalára, ahonnan a legutolsó módosítás dátumát lehetett megszerezni.

Kimenetként készült egy .csv fájl, ami az oldalhierarchiát tartalmazta: hogy melyik weblapnak melyek a szülőoldalai, egy másik .csv táblázat, ami a lapok főbb adatai (mint az eredeti URL, cím, módosítás dátuma) mellett a tulajdonképpeni szövegtörzset tartalmazta egy-egy sorban. Készült még egy fájl, ami soronként tartalmazta az összes hozzászólást, szintén főbb adataikkal, végül egy hibakeresésre szolgáló fájl, ahol ömlesztve volt a fent említett egyetlen szöveges mező tartalma a szövegtörzzsel és a hozzászólásokkal – ha netán valamit elrontottam volna az utófeldolgozásnál.

A szkript megvalósítása UBot Studio-val

Mivel az egész folyamat nem tűnt túl bonyolultnak, ezért az Ubot Studio-ra esett a választásom a megvalósításnál. Ez egy olyan vizuális programozási felületet ad, ami elsősorban kevés elágazással és egymásba ágyazott ciklussal rendelkező, lineáris logikájú szkripteknél tud jól működni. Ezt a szoftvert tulajdonképpen egy online marketingeseknek való autmatizáló rendszerként hírdetik, de a fejlesztésének eredeti célja a weboldalak szkrépelése és szpemmelése volt linkbeküldésekkel, hozzászólások elküldésével, stb. Ettől függetlenül még számos egyéb webes automatizációs feladatra használható. Egyik legjobb funkciója, hogy segítségével .exe formátumú, Windows operációs rendszereken egyszerűen futtatható programokat építhetünk. A botok futtatásához tehát nincsen szükség magára – az egyébként elég borsos árú – szoftverre. Mivel magyar nyelvterületen kb. rajtam kívül még egy-két helyen használták ezt a tartalomkezelő rendszert, ezért ezt az .exe fájlt nem raknám ki letölthető formában, de ha írsz nekem, vagy hozzászólsz ehhez a bejegyzéshez, akkor szívesen elküldöm, ha szükséged lenne a saját ZWiki oldalad költöztetéséhez erre.

A másik érdekes koncepciója az Ubot Studionak, hogy a vizuális programozási nézetből – ahol dobozokat húzkodsz, majd nyitsz meg a paraméterek beállítása céljából – át lehet váltani kódnézetbe is, ahol egy egyszerű szintaxisú kódnyelv segítségével is áttekintheted illetve szerkesztheted a szkriptedet. Egy kis türelemmel és az alábbi kód elolvasásával megértheted, hogy pontosan hogyan is épült fel ez a szkript:

 ui text box("Domain to scrape (without http(s)://):",#domain)
 allow javascript("No")
 navigate("{#domain}/FrontPage/contents","Wait")
 wait for browser event("Everything Loaded","")
 wait(5)
 set(#scraped,$scrape attribute(<class="formcontent">,"innerhtml"),"Global")
 add list to list(%pageurls,$find regular expression(#scraped,"(?<=href=\")[^\"]+"),"Delete","Global")
 loop($list total(%pageurls)) {
     set(#pageurl,$list item(%pageurls,1),"Global")
     navigate(#pageurl,"Wait")
     wait for browser event("Everything Loaded","")
     wait(5)
     set(#content,$scrape attribute(<class="content">,"innerhtml"),"Global")
     set(#content,$replace regular expression(#content,"<a\\ class=\"new\\ .+?(?=</a>)</a>","<!-- no wikipage yet -->"),"Global")
     set(#content,$replace(#content,$new line,$nothing),"Global")
     set(#content,$replace regular expression(#content,"\\t"," "),"Global")
     set(#contentonly,$replace regular expression(#content,"<p><div\\ class=\"subtopics\"><a\\ name=\"subtopics\">.+",$nothing),"Global")
     set(#contentonly,$replace regular expression(#contentonly,"<p><a name=\"comments\">.+",$nothing),"Global")
     set(#contentonly,$replace regular expression(#contentonly,"<a name=\"bottom\">.+",$nothing),"Global")
     add list to list(%parents,$scrape attribute(<class="outline expandable">,"innertext"),"Delete","Global")
     set(#parentlist,$list item(%parents,0),"Global")
     clear list(%parents)
     add list to list(%parents,$list from text(#parentlist,$new line),"Delete","Global")
     set(#parentlist,$replace(#parentlist,$new line,";"),"Global")
     set(#posttitle,$list item(%parents,$eval($subtract($list total(%parents),1))),"Global")
     set(#posttitle,$replace(#posttitle," ...",$nothing),"Global")
     if($comparison($list total(%parents),"> Greater than",1)) {
         then {
             set(#parent,$list item(%parents,$eval($subtract($list total(%parents),2))),"Global")
         }
         else {
             set(#parent,$nothing,"Global")
         }
     }
     append to file("{$special folder("Desktop")}\\{#domain}-page-hierarchy.csv","{#pageurl}    {#posttitle}    {#parent}    {#parentlist}    {$new line}","End")
     clear list(%parents)
     add list to list(%comments,$find regular expression(#content,"<p><a[^>]+name=\"msg.+?(?=<p><a[^>]+name=\"msg.+)"),"Delete","Global")
     loop($list total(%comments)) {
         set(#comment,$list item(%comments,0),"Global")
         set(#date,$find regular expression(#comment,"(?<=name=\"msg)[^@]+"),"Global")
         set(#title,$find regular expression(#comment,"(?<=<b>).+?(?=</b>\\ --)"),"Global")
         set(#title,$replace regular expression(#title,"<[^>]+>",$nothing),"Global")
         set(#author,$find regular expression(#comment,"(?<=</b>\\ --).+?(?=<a\\ href=\"{#pageurl})"),"Global")
         set(#author,$replace regular expression(#author,"<[^>]+>",$nothing),"Global")
         set(#author,$replace regular expression(#author,",\\ *$",$nothing),"Global")
         set(#comment,$find regular expression(#comment,"(?<=<br(|\\ /)>).+"),"Global")
         set(#comment,"<p>{#comment}","Global")
         set(#comment,$replace regular expression(#comment,"\\t"," "),"Global")
         append to file("{$special folder("Desktop")}\\{#domain}-page-comments.csv","    {#pageurl}    {#date}    {#title}    {#author}    {#comment}    {$new line}","End")
         remove from list(%comments,0)
     }
     navigate("{#pageurl}/history","Wait")
     wait for browser event("Everything Loaded","")
     wait(5)
     scrape table(<outerhtml=w"<table>*">,&edithistory)
     set(#lastedited,$table cell(&edithistory,0,4),"Global")
     clear table(&edithistory)
     append to file("{$special folder("Desktop")}\\{#domain}-page-content-raw.csv","{#pageurl}    {#lastedited}    {#content}    {$new line}","End")
     append to file("{$special folder("Desktop")}\\{#domain}-page-content-only.csv","{#pageurl}    {#posttitle}    {#lastedited}    {#contentonly}    {$new line}","End")
     remove from list(%pageurls,0)
 }

2. lépés: A tartalom feltöltése erre a WordPress oldalra

Miután végigment a szkript az összes tartalmon és strukturált formátumba hozta a tartalmat, majd lementette .csv fájlokba, további szkriptekre volt szükségem ahhoz, hogy ezekből a táblázatokból „táplálkozva” feltöltsem a tartalmakat a WordPress oldalra. Ennél a résznél is egy hasonló technológiához folyamodtam, tehát a szkriptem bejelentkezett az oldal admin felületére, majd megnyomta az „Új oldal létrehozása” gombot, kitöltötte a szerkesztő űrlap különböző mezőit, kiválasztotta a legördülő menükben a megfelelő opciókat, majd megnyomta a „Közzététel” gombot. Hogy hogyan és miért így csináltam, és mi volt ennek az értelme, arról talán majd egy következő bejegyzésben lesz szó.

Mivel az online marketing területére az információépítészet felől érkeztem, egy tartalomkezelő rendszer kódjának barkácsolása, vagy akár egy komplett WordPress sablon létrehozása sosem okozott lelki válságot. Bár ezekben a tevékenységekben is volt egy nagy adag logika, programozásnak ezt legkevésbé sem nevezném. Öt éve azonban tulajdonképpen egy véletlen folytán megismertem egy olyan szoftvert, amivel én is egyszerűen megírhattam kisebb-nagyobb programocskákat, ezzel pedig új szintre emelhettem mindazt, amit azóta online marketing vagy webfejlesztés címén csinálok.

Web automatizálás: vissza a programozáshoz

Én még a nyolcvanas években kaptam az első számítógépem, amikor szinte minden számítógéptulajdonos tudott valamicskét programozni is. Valahogy azonban ez sosem feküdt annyira, így végül nem lett belőlem programozó. 2012 elején azonban újból kódolni kezdtem: ekkoriban mindenféle, keresőmarketinggel kapcsolatos munkákat csináltam, és egy ideje már azon voltam, hogy további olyan szoftvereket találjak, amik még jobban segítettek volna automatizálni a tömeges linképítéssel kapcsolatos szolgáltatásainkat.

Miközben egy újabb és jobb linkbeküldő, linkbeküldés-automatizáló szoftvert kerestem, rábukkantam egy általános web automatizációs szoftverre. Ezt és a hozzá hasonló programokat elsősorban web szpemmelésre találták ki, azonban megláttam bennük azt is, hogy emellett mennyi minden másra is használhatóak még. Az első komolyabb szkriptemet két hétig írtam, majd újabb két hetet vett igénybe, míg a kezdeti tapasztalatok alapján újraírtam mindent, de a végén kaptam egy olyan programocskát, ami sokáig ki tudta váltani egy fél ember munkáját.

Az alapprobléma ugyanis az volt, hogy ha mi beküldtünk egy linket egy linkgyűjteménybe, akkor szinte sosem tudtuk, hogy hol, milyen URL-en fog megjelenni, így a legtöbb linkgyűjteményben utólag, kézzel kellett leellenőrizni, hogy jóváhagyták-e a linkbeküldéseket. Ehelyett a kis szkriptem végigment a katalógusokon, rákeresett a linkjeinkre az oldalakon magán és a keresőkben, majd összeírta, hogy hová, milyen paraméterekkel kerültünk be. Pont úgy zajlott, mintha valaki kézzel megcsinálta volna mindezt, viszont a „robotnak” nem kellett fizetést adni, és utána járulékokat fizetni.

Ekkor még nem is gondoltam, hogy a későbbiekben mennyi minden egyébre fogom használni ezt az újonnan megismert, vizuális programozási technológiát, és ez mennyire fogja megváltoztatni mindazt, amivel és ahogy foglalkozom majd az elkövetkezendőekben.

 

Vizuális programozás online marketingeseknek

Az elmúlt öt évben egyre több és több dolgot csináltam, és egyre több tapasztalatot szereztem ezekkel az eszközökkel. Mindez fokozatosan alakította, hogy mit gondolok arról, hogy mi az, amit egy modern oline marketingesnek tudnia kellene az adatok gyűjtésével, feldolgozásával és értékelésével kapcsolatban – származzon az a webről, saját látogatottsági statisztikákból, vagy egyéb belső adatforrásból.

Tény, hogy vannak tudományosabb, gyorsabb és hatékonyabb módjai is annak, hogy mindenféle weboldalakkal vagy adatokkal kapcsolatos repetitív feladatokat automatizáljunk. Nekem azonban rengeteg segítséget adott, hogy különböző ötleteimet gyorsan meg tudjam valósítani, legyen szó adatfeldolgozásról, vagy fárasztó, monoton feladatok felgyorsításáról, vagy akár olyan projektek megvalósításáról, amit emberi erővel szinte lehetetlen lenne megcsinálni. Mindezt pedig számottevő programozói tudás nélkül, illetve programozó közreműködése nélkül is megtehettem.

A programozás diadalmenete

Tekintve, hogy már az eredeti szakmám, az építészet területén is egyre divatosabb a vizuális programozás és az algoritmikus tervezés, talán nem túlzás azt állítani, hogy lassan egyre több és több szakma művelői számára lesz elengedhetetlen, hogy hosszabb-rövidebb algoritmusokat maguk is meg tudjanak írni. Így talán itt is érdeklődésre tarhat számot, ha ezután részletesebben is írni fogok arról, hogy az online marketingben, keresőoptimalizálásban, keresőmarketingben és webfejlesztésben hogyan segített előrelépni a vizuális programozás.