Pri premýšľaní nad obsahom ďalšieho článku o PS ma napadlo spracovanie html dokumentu. Kedže je to pre mňa neprebádaná oblasť, napadlo ma, že by bolo dobré bádať spolu. Zažiť tak pocit úspechu, poprípade neúspechu.
V tomto článku nebudem vysvetľovať nič podrobnejšie. Jednoducho som si zadal cieľ, ktorý sa pokúsim dosiahnuť. Pričom zdokumentujem môj podrobný postup. Možno vás tak ponorím do tajov počítačového sveta.
Ako ja vždy vravím programátor musím mať nervy a riadnu trpezlivosť, aby úspešne došiel do cieľa. Takže ak premýšľate nad programovaním, a v polovici článku sa vám už nebude chciet dalej čítať, vedzte že to asi nebude váš správny smer.
Už dávnejšie ma napadla myšlienka sparsovania webu. Proste načítam cez skript web, a zobrazím si vo vlastnom prehliadači len úryvky stránky, ktoré sú pre mňa zaujímavé. Takú vlastnú " rss čítačku ".
Ako prvé potrebujem vedieť, ako získam štruktúru webstránky do powershellu (PS). Mohol by som použiť znalosti z predošlých článkov o http requeste. Dobrá možnosť. Myslím však že by bolo jednoduchšie na to použiť prehliadač. Keby že to robím cez spomínaný request, tak by som asi nemal prístup k javascriptu. A ak hej, tak niejakou obkľukov.
Strýčka googlu sa teda spýtam na dotaz "PowerShell DOM", hneď prvý výsledok je vcelku zaujímavý. Dočítal som sa tam síce že to týmto spôsobom nieje možné... neverte všetkému čo sa dočítate.
Ešte sa pozriem do .NET dokumentácie či tam nenájdem niečo na túto tému. Hľadám zbežným prereraním nejakú zmienku o DOM alebo Document. Mohlo by to byť niekde pod kategóriou System.Net alebo možno System.Web . Otváram, hľadám nejaký výstižný nadpis o dokumente. Ale nič nenachádzam. Vraciam sa spať na výpis kategórií. Všimol som si kategóriu "Microsoft.JScript Namespaces". To by mohlo byť to čo potrebujem. Otváram, je tam podkateória "Microsoft.JScript" , otváram. Hmm, tam je toho dosť...
Zbežne prezerám nadpisy a hľadám niejakú súvislosť z niečim , čo poznám , alebo som už niekde použil. Predpokladám že tam nájdem súvislosti z JavaScriptom...
Nachádzam eval,try, throw. Z toho čo som vydel usudzujem, že táto knihovna je základom JS ako ho poznám. Je to ten surový JS. Nerád by som sa zdržoval z jeho učením, idem sa teda vrátiť o krok spat.
Google mi našiel ukážku na jednom fóre. Písali tam, že to nieje týmto spůsobom možné. Avšak podľa skúseností viem, že to ked to niekdo nevie, tak to neznamená že sa to nedá.
Otváram si konzolu Ps . Zadávam kód :
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate("http://kreveta.net/")
Spúštiam. Výborne, otvoril sa mi prehliadač maxthon (neviem prečo práve on), a načítala sa mi stránka Krevety. Mohlo by to fungovať.
Načítanie stránky chvíľu trvá. nemôžem otvoriť stránku, a prečítať jej zdroják hneď na to. Otváram google. Hľadám "PowerShell pause". Prvý výsledok je na prístupovú klávesu. Druhý je to čo mi treba, funkcia sleep. Kopírujem riadok do zdrojáku. Mám v ňom :
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate("http://kreveta.net/")
$doc = $ie.Document
Start-Sleep -m 10000
$doc
Spúšťam... Super, funguje. Pauza je však veľká, mením číslo na 5000, spúšťam. Stále veľa, dávam 3000, to už sa dá.
Výsledok však nieje vôbec taký, aký by som potreboval. Potrebujem HTML dokument. Namiesto toho mi vypísalo kopu premenných. Väčšina nemá obsah.
Prezerám ich, hľadám niečo, kde by mohla byť uložená štruktúra dokumentu. Premenná "documentElement" vyzerá sľubne. Do otvoreného príkazového riadka kopírujem príkaz
Výsledok je dobrý. Našiel som schované html. Ten je uložený v premennej "innerHTML" . Výborne. Našiel som spojitosti, vidím položky ako innerHTML, onkeydown, outerHTML a ďalšie. Teraz už viem, že som našiel DOM element html dokumetu podľa špecifikácie w3c. Otváram špecifikáciu zo záložiek, určite sa mi čoskoro zíde.
Potrebujem zistiť druh elemetu, aby som vedel, ako k nemu pristupovať. Prezerám znova posledný výpis v ps konzole, a nachádzam "tagName : HTML" . V špecifikácii hľadám tento tag, je hneď prvý v zozname, čítam. Myslím že som našiel hlavný DOM element. Skúšam napísať do konzoly
Podľa w3c by mi to malo vyhodiť titulok stránky. v našom prípade "Úvod - Kreveta.NET". Výsledok je prázdny. Niečo som zle pochopil. Prezerám znova výpis v konzole. Hľadám v ktoróm výpise mi ukázalo titulok, možno tak zistím kde je html element. Skúšam :
Zistil som , že sa mi musel niekde vymazať obsah stránky. Preto boli pokusy neúspešné. Musím ich zopakovať znovu. Spúšťam script :
Podarilo sa mi získať titulok stránky. Predpokladám, že premenná "$doc" je objektom, hmmm . Akým ? Prezerám jej obsah... Zisťujem že je to nejaký hlavný DOM objekt. Snažím sa nájsť spôsob, ako sa dostať k určenému obsahu stránky. Skúšam príkazy
$doc.documentElement.head //prazdne
$doc.documentElement.children
Vypísalo mi obsah elementu HEAD.
Pri jeho skúmaní som zistil že my vypísalo Head, a hned za ním aj Body. Predpokladám že posledný príkaz obsahuje pole elementov. Preto skúšam daľej:
Teraz keď mám predstavu o tom, čo mám k dispozícií. Môžem sa pustiť do googlovania. Keby som tú predstavu nemal, tak by som sa asi výsledku nedohľadal. Tiež je treba poznamenať že doterajšia práca mi trvala asi 10 minút čistého času.
Do googlu zadávam ".net documentElement" a to preto že celý čas používam platformu .NET. Takisto som zistil že moja premenná má vlastnosť documentElement v ktorej sa nachádza pole z vnorenými elementami. Ja potrebujem nájsť spôsob, ako k nim pristupovať.
Hneď prvý výsledok mi dal jasnú odpoveď, obsah premennej je objekt dokumentu XML. Zaujímavé však, pamätáte si ešte na prvé fórum ktoré som navštívil, tam kde písali že... .
Do konzole píšem:
To nedáva zmysel. Podla poslednej nájdenej stránky by to malo fungovať. Je tam rozdiel už v tom , že tam sa spomína count a ja mám length. Musí to byť teda niečo iné, znova googlim . PS mi pri pokuse o prístup k prvkom vyhodil hlášku "Unable to index into an object of type System.__ComObject.". V úvodzovkách ju píšem do googlu. Prehľadávam výsledky. Prvý nič moc, ani druhý. Prestávam pozerať obsah výsledkov, čítam už len nadpisy čo mám vo výsledkoch googlu. Ten piaty vyzerá sľubne Add method not accessibe from Powershell? in Powershell. Otváram, zbežne prezerám. Do očí mi padol riadok "$inDesign.Documents | get-member" je tam prístup k dokumentu. Skúšam to napísať do konzole
Vypísalo mi to všetky metódy, a vlastnosti objektu. Avšak nie metody poľa, ale všetkých objektov v ňom uložených. Zaujímavý príkaz. Prezerám výpis, znova hľadám spojitosti z niečim. Spojitostí tam je viacej než dosť. Avšak nie z xml ale z pôvodným zistením, že sa jedná o html element. Zameral som sa na funkciu getElementsByTagName. Znova testujem :
Znova sa musím vrátiť k poslednému článku, pozerám ho pozornejšie.
Pozastavil som sa nad týmto :
Otváram si no konzolu, a zisťujem načo slúži ten posledný riadok.
Keď som zadal predtým $doc.childNodes |Get-Member, tak mi vypísalo metódy a funkcie objektov, ktoré boli uložené v tom poli. Ale nevypísalo mi metódy, priamo toho poľa. V tejto testovacej konzole mi však vypísalo metódy poľa.
Prepnem sa na hlavnú konzolu, a zapisujem riadok
Už ako som tam videl to slovíčko item, vedel som čo s tým mám robiť. Je to totiž definícia w3c, čiže je to javascript ako ho poznám. Teraz keď mám tieto zistenia, Spravím pár testov, či sa náhodou nemýlim. Riadim sa posledným výpisom objektu.
Test prebehol presne podla očakávaní, pokračoval by som v ňom, keby že má nejakú pochybnosť. Čo však nemám.
Skompletujem si veci,ktoré som zistil, ktoré viem a ktoré potrebujem vedieť.
Najväčší problém bola pre mňa nepreskúmaná oblasť PS html dokumentu. Zistil som však, že k obsahu stránky môžem pristupovať pomocou klasického prehliadača , za použitia klasického javascriptu. Neviem ako vy, ale ja vždy začínam od vecí ktoré sú pre mňa najnemožnejšie. Na ktorých by to mohlo stroskotať.
Takže mám v PS prehliadač, jeho dokument a prístup k nemu, pomoc javascriptu.
Môj pôvodný zámer bol vytvoriť vlastný prehliadač, takú malú rss čítačku stránky. K tomu mi je potrebné vedieť taký prehliadač zostaviť. Ja si postačím aj z klasickým oknom, textom, tlačítkami. Ak sa mi podarí, spravím aj tlačítko spať a zobrazovanie obrázkov. Avšak už teraz viem, že to by boli potrebné ďalšie zisťovania.
Niet nad kvalitnú zbierku užitočných informácií vždy po ruke (ďakujem ti strýčku za synchronizáciu záložiek). Preto si všetky užitočné informácie pri vyhľadávaní ukladám.
V týchto mojich záložkách mám veci ohľadne win forms. Čo sú tie spomínané okná a jeho elementy. Mám tam takisto aj veľa iných informácií, ktoré sa mi môžu zísť. Takže vyhľadávanie mi už asi odpadá. Môžeme ísť teda na vec.
Kto nevie čo tá skratka znamená... Ale určite to vie každý. Je to predsa Copy and pastle. Ja to využívam strašne moc, a strašne veľakrát som a tento zlozvyk doplatil. To neboli minúty, alebo hodiny odstraňovania chýb týmto spôsobených. Raz som hľadal chybu 3 týždne a zistil som že som skopíroval zlé slovíčko... Naučiť sa prstoklad by mi trvalo menej. Len tým chcem povedať, že neodporúčam nikomu používať tento spôsob.
Vytvorím si nový script v programe powerGUI.
Potrebujem získať dokument, lenže funkcia sleep nieje dostatočná. Potrebujem ju zabezpečiť, proti pomalému načítaniu stránky. Hľadám teda niečo ako onModuleLoad
skúsim to teda pomocou pôvodného sleep. Vytvorím si prázdny script, napíšem doňho smyčku while a skopírujem všetko priamo do novej konzole.
Takto to nepôjde. Smyčku mi nezoberie hneď , ale až po stlačení enteru. Skúsim to dať do funkcie, to určite pôjde. Otváram môj starší článok. Hľadám syntax a funkcie argumetu.
Pôvodný script prepisujem na :
Funguje. výsledkom je načítaný dokument.
Teraz potrebujem vytiahnuť zo stránky potrebný text. Otvorím si chrome, stlačím klávesovú skratku Ctrl+Shift+I. Zobrazím si štruktúru HTML. Podľa nej získavam prístup k textu. Zaujímajú ma nadpisy článkov, čas a autor.
V obsahu už je presne to čo sme hľadali. Každý príspevok má 6 elementov div. Zabudol som na začiatku tejto časti povedať, že si musím prepisovať výsledky. Teraz ich už v konzole nenájdem. Ja som ich však zapisoval tu, do článku a tak ich mám po ruke. Môžem to teda nijak uceliť do pôvodného scriptu z funkciou na otvorenie dokumentu. Po zapísaní mi ostalo:
Teraz mi to treba už len zobraziť. Myslím si však, že tento článok už dávno presiahol normál, takže vám prajem príjemnú zábavu a silné nervy.
Taký urýchlený výsledok je možné pozrieť po spustení tohto kódu :
Prosím o vyjadrenie svojho názoru na článok komentárom, alebo pridaním Líbí/Nelíbí.
Ako ja vždy vravím programátor musím mať nervy a riadnu trpezlivosť, aby úspešne došiel do cieľa. Takže ak premýšľate nad programovaním, a v polovici článku sa vám už nebude chciet dalej čítať, vedzte že to asi nebude váš správny smer.
Môj cieľ
Už dávnejšie ma napadla myšlienka sparsovania webu. Proste načítam cez skript web, a zobrazím si vo vlastnom prehliadači len úryvky stránky, ktoré sú pre mňa zaujímavé. Takú vlastnú " rss čítačku ".
Získajme si podklady
Ako prvé potrebujem vedieť, ako získam štruktúru webstránky do powershellu (PS). Mohol by som použiť znalosti z predošlých článkov o http requeste. Dobrá možnosť. Myslím však že by bolo jednoduchšie na to použiť prehliadač. Keby že to robím cez spomínaný request, tak by som asi nemal prístup k javascriptu. A ak hej, tak niejakou obkľukov.
Strýčka googlu sa teda spýtam na dotaz "PowerShell DOM", hneď prvý výsledok je vcelku zaujímavý. Dočítal som sa tam síce že to týmto spôsobom nieje možné... neverte všetkému čo sa dočítate.
Ešte sa pozriem do .NET dokumentácie či tam nenájdem niečo na túto tému. Hľadám zbežným prereraním nejakú zmienku o DOM alebo Document. Mohlo by to byť niekde pod kategóriou System.Net alebo možno System.Web . Otváram, hľadám nejaký výstižný nadpis o dokumente. Ale nič nenachádzam. Vraciam sa spať na výpis kategórií. Všimol som si kategóriu "Microsoft.JScript Namespaces". To by mohlo byť to čo potrebujem. Otváram, je tam podkateória "Microsoft.JScript" , otváram. Hmm, tam je toho dosť...
Zbežne prezerám nadpisy a hľadám niejakú súvislosť z niečim , čo poznám , alebo som už niekde použil. Predpokladám že tam nájdem súvislosti z JavaScriptom...
Nachádzam eval,try, throw. Z toho čo som vydel usudzujem, že táto knihovna je základom JS ako ho poznám. Je to ten surový JS. Nerád by som sa zdržoval z jeho učením, idem sa teda vrátiť o krok spat.
Google mi našiel ukážku na jednom fóre. Písali tam, že to nieje týmto spůsobom možné. Avšak podľa skúseností viem, že to ked to niekdo nevie, tak to neznamená že sa to nedá.
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate("")
$doc = $ie.Document
$doc.getElementByID("")
$ie.navigate("
$doc = $ie.Document
$doc.getElementByID("
Prvý pokus
Otváram si konzolu Ps . Zadávam kód :
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate("http://kreveta.net/")
Spúštiam. Výborne, otvoril sa mi prehliadač maxthon (neviem prečo práve on), a načítala sa mi stránka Krevety. Mohlo by to fungovať.
Načítanie stránky chvíľu trvá. nemôžem otvoriť stránku, a prečítať jej zdroják hneď na to. Otváram google. Hľadám "PowerShell pause". Prvý výsledok je na prístupovú klávesu. Druhý je to čo mi treba, funkcia sleep. Kopírujem riadok do zdrojáku. Mám v ňom :
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate("http://kreveta.net/")
$doc = $ie.Document
Start-Sleep -m 10000
$doc
Spúšťam... Super, funguje. Pauza je však veľká, mením číslo na 5000, spúšťam. Stále veľa, dávam 3000, to už sa dá.
Výsledok však nieje vôbec taký, aký by som potreboval. Potrebujem HTML dokument. Namiesto toho mi vypísalo kopu premenných. Väčšina nemá obsah.
Pokus omyl, aneb niečo hľadám
Prezerám ich, hľadám niečo, kde by mohla byť uložená štruktúra dokumentu. Premenná "documentElement" vyzerá sľubne. Do otvoreného príkazového riadka kopírujem príkaz
$doc.documentElement
Výsledok je dobrý. Našiel som schované html. Ten je uložený v premennej "innerHTML" . Výborne. Našiel som spojitosti, vidím položky ako innerHTML, onkeydown, outerHTML a ďalšie. Teraz už viem, že som našiel DOM element html dokumetu podľa špecifikácie w3c. Otváram špecifikáciu zo záložiek, určite sa mi čoskoro zíde.
Potrebujem zistiť druh elemetu, aby som vedel, ako k nemu pristupovať. Prezerám znova posledný výpis v ps konzole, a nachádzam "tagName : HTML" . V špecifikácii hľadám tento tag, je hneď prvý v zozname, čítam. Myslím že som našiel hlavný DOM element. Skúšam napísať do konzoly
$doc.documentElement.title
Podľa w3c by mi to malo vyhodiť titulok stránky. v našom prípade "Úvod - Kreveta.NET". Výsledok je prázdny. Niečo som zle pochopil. Prezerám znova výpis v konzole. Hľadám v ktoróm výpise mi ukázalo titulok, možno tak zistím kde je html element. Skúšam :
$doc.title // nejde
$doc.document.title //zase nič
$doc.document // prázdne
$doc.documentElement.document //nič
$doc.documentElement.document.title //nič
$doc
$doc.document.title //zase nič
$doc.document // prázdne
$doc.documentElement.document //nič
$doc.documentElement.document.title //nič
$doc
Zistil som , že sa mi musel niekde vymazať obsah stránky. Preto boli pokusy neúspešné. Musím ich zopakovať znovu. Spúšťam script :
clear
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate("http://kreveta.net/")
$doc = $ie.Document
Start-Sleep -m 3000
$doc.document.title //nič
$doc.documentElement.document.title //žiadny výsledok
$doc.documentElement.title //ani teraz, to nieje možne
$doc // aha, dokument je prázdny. asi musím prestaviť časovač
$doc = $ie.Document // nastavujem už načítanú stránku
$doc.document.title //skúšam vypísať titulok, žiadny výsledok
$doc //zobrazujem obsah premenej, stránka tam je.
$doc.document.title
echo $doc.document.title
$doc.title //Úvod - Kreveta.NET
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate("http://kreveta.net/")
$doc = $ie.Document
Start-Sleep -m 3000
$doc.document.title //nič
$doc.documentElement.document.title //žiadny výsledok
$doc.documentElement.title //ani teraz, to nieje možne
$doc // aha, dokument je prázdny. asi musím prestaviť časovač
$doc = $ie.Document // nastavujem už načítanú stránku
$doc.document.title //skúšam vypísať titulok, žiadny výsledok
$doc //zobrazujem obsah premenej, stránka tam je.
$doc.document.title
echo $doc.document.title
$doc.title //Úvod - Kreveta.NET
Podarilo sa mi získať titulok stránky. Predpokladám, že premenná "$doc" je objektom, hmmm . Akým ? Prezerám jej obsah... Zisťujem že je to nejaký hlavný DOM objekt. Snažím sa nájsť spôsob, ako sa dostať k určenému obsahu stránky. Skúšam príkazy
$doc.documentElement.head //prazdne
$doc.documentElement.children
Vypísalo mi obsah elementu HEAD.
Pri jeho skúmaní som zistil že my vypísalo Head, a hned za ním aj Body. Predpokladám že posledný príkaz obsahuje pole elementov. Preto skúšam daľej:
$doc.documentElement.children[0]// error
$doc.documentElement.children[1]// error
$doc.documentElement.children(0)// error
$doc.documentElement.children.getFirst //prazdne
$doc.documentElement.children[1]// error
$doc.documentElement.children(0)// error
$doc.documentElement.children.getFirst //prazdne
Pokus omyl nestačí, treba aj niečo naštudovať
Teraz keď mám predstavu o tom, čo mám k dispozícií. Môžem sa pustiť do googlovania. Keby som tú predstavu nemal, tak by som sa asi výsledku nedohľadal. Tiež je treba poznamenať že doterajšia práca mi trvala asi 10 minút čistého času.
Do googlu zadávam ".net documentElement" a to preto že celý čas používam platformu .NET. Takisto som zistil že moja premenná má vlastnosť documentElement v ktorej sa nachádza pole z vnorenými elementami. Ja potrebujem nájsť spôsob, ako k nim pristupovať.
Hneď prvý výsledok mi dal jasnú odpoveď, obsah premennej je objekt dokumentu XML. Zaujímavé však, pamätáte si ešte na prvé fórum ktoré som navštívil, tam kde písali že... .
Do konzole píšem:
$root = $doc.firstChild
$root.childNodes.length //0
$root.length //106
$root[0] //error
For Each $y in $root echo $y //error
$root[52] // error
$root.hasChildNodes//vypis metody
$root.hasChildNodes() //false
$root.childNodes.length //0
$root.length //106
$root[0] //error
For Each $y in $root echo $y //error
$root[52] // error
$root.hasChildNodes//vypis metody
$root.hasChildNodes() //false
To nedáva zmysel. Podla poslednej nájdenej stránky by to malo fungovať. Je tam rozdiel už v tom , že tam sa spomína count a ja mám length. Musí to byť teda niečo iné, znova googlim . PS mi pri pokuse o prístup k prvkom vyhodil hlášku "Unable to index into an object of type System.__ComObject.". V úvodzovkách ju píšem do googlu. Prehľadávam výsledky. Prvý nič moc, ani druhý. Prestávam pozerať obsah výsledkov, čítam už len nadpisy čo mám vo výsledkoch googlu. Ten piaty vyzerá sľubne Add method not accessibe from Powershell? in Powershell. Otváram, zbežne prezerám. Do očí mi padol riadok "$inDesign.Documents | get-member" je tam prístup k dokumentu. Skúšam to napísať do konzole
$doc.childNodes |Get-Member
Vypísalo mi to všetky metódy, a vlastnosti objektu. Avšak nie metody poľa, ale všetkých objektov v ňom uložených. Zaujímavý príkaz. Prezerám výpis, znova hľadám spojitosti z niečim. Spojitostí tam je viacej než dosť. Avšak nie z xml ale z pôvodným zistením, že sa jedná o html element. Zameral som sa na funkciu getElementsByTagName. Znova testujem :
$doc.childNodes.getElementsByTagName("HTML") //error
$doc.childNodes.getElementsByTagName //nič
$doc.childNodes.getElementsByTagName|Get-Member //error
$doc.childNodes[0] //error
$doc.childNodes.html //nič
$doc.childNodes.HTML //nič
$doc.childNodes.1 //jasne že error, :-D
$doc.childNodes.length // 2, to sedí. mam head, a html
$doc.childNodes.count // nič
$doc.childNodes.getElementsByTagName //nič
$doc.childNodes.getElementsByTagName|Get-Member //error
$doc.childNodes[0] //error
$doc.childNodes.html //nič
$doc.childNodes.HTML //nič
$doc.childNodes.1 //jasne že error, :-D
$doc.childNodes.length // 2, to sedí. mam head, a html
$doc.childNodes.count // nič
Znova sa musím vrátiť k poslednému článku, pozerám ho pozornejšie.
Pozastavil som sa nad týmto :
$a = @(1,2,3,4)
and give you the members on that..
$a |Get-Member
object, and give you the members on that.
get-Member -inputobject $A
and give you the members on that..
$a |Get-Member
object, and give you the members on that.
get-Member -inputobject $A
Otváram si no konzolu, a zisťujem načo slúži ten posledný riadok.
$a = @(1,2,3,4)
$a |Get-Member // výsledok je obdobný ako predtým
get-Member -inputobject $a
$a |Get-Member // výsledok je obdobný ako predtým
get-Member -inputobject $a
Keď som zadal predtým $doc.childNodes |Get-Member, tak mi vypísalo metódy a funkcie objektov, ktoré boli uložené v tom poli. Ale nevypísalo mi metódy, priamo toho poľa. V tejto testovacej konzole mi však vypísalo metódy poľa.
Na každú ďalšiu vec, čo nemá súvislosti z tou predchodzou otváram nové okno (ps, win, chrome). A to z dôvodu, že pri takomto testovaní si často prezerám predošlý výpis. Nebolo by dobré tam mať nepotrebné veci. Pozerám ho z jednoduchého dôvodu, stále skúšam iné veci, z iného smeru. Je možné že na začiatku mi niečo išlo, ale ako sa postupne presmerovávam na úplný iný koniec, tak to zo začiatku mi už nejde, tak sa vrátim, a spomeniem si akým spôsobom to fungovalo. Skombinujem , a mám.
Prepnem sa na hlavnú konzolu, a zapisujem riadok
get-Member -inputobject $doc.childNodes // a hľa, výsledok presne ktorý mi treba
$doc.childNodes.item(1) //výpis html elementu "HTML"
$doc.childNodes.item(1) //výpis html elementu "HTML"
Už ako som tam videl to slovíčko item, vedel som čo s tým mám robiť. Je to totiž definícia w3c, čiže je to javascript ako ho poznám. Teraz keď mám tieto zistenia, Spravím pár testov, či sa náhodou nemýlim. Riadim sa posledným výpisom objektu.
$HTMLElement = $doc.childNodes.item(1)
$HTMLElement.childNodes.length //2
$HTMLElement.childNodes.item(1) // výpis elementu "BODY"
$BODYElement = $HTMLElement.childNodes.item(1)
$BODYElement.tagName //BODY
$HTMLElement.childNodes.length //2
$HTMLElement.childNodes.item(1) // výpis elementu "BODY"
$BODYElement = $HTMLElement.childNodes.item(1)
$BODYElement.tagName //BODY
Test prebehol presne podla očakávaní, pokračoval by som v ňom, keby že má nejakú pochybnosť. Čo však nemám.
Zhromažďujem podklady
Skompletujem si veci,ktoré som zistil, ktoré viem a ktoré potrebujem vedieť.
Najväčší problém bola pre mňa nepreskúmaná oblasť PS html dokumentu. Zistil som však, že k obsahu stránky môžem pristupovať pomocou klasického prehliadača , za použitia klasického javascriptu. Neviem ako vy, ale ja vždy začínam od vecí ktoré sú pre mňa najnemožnejšie. Na ktorých by to mohlo stroskotať.
Takže mám v PS prehliadač, jeho dokument a prístup k nemu, pomoc javascriptu.
Môj pôvodný zámer bol vytvoriť vlastný prehliadač, takú malú rss čítačku stránky. K tomu mi je potrebné vedieť taký prehliadač zostaviť. Ja si postačím aj z klasickým oknom, textom, tlačítkami. Ak sa mi podarí, spravím aj tlačítko spať a zobrazovanie obrázkov. Avšak už teraz viem, že to by boli potrebné ďalšie zisťovania.
Niet nad kvalitnú zbierku užitočných informácií vždy po ruke (ďakujem ti strýčku za synchronizáciu záložiek). Preto si všetky užitočné informácie pri vyhľadávaní ukladám.
V týchto mojich záložkách mám veci ohľadne win forms. Čo sú tie spomínané okná a jeho elementy. Mám tam takisto aj veľa iných informácií, ktoré sa mi môžu zísť. Takže vyhľadávanie mi už asi odpadá. Môžeme ísť teda na vec.
C&P
Kto nevie čo tá skratka znamená... Ale určite to vie každý. Je to predsa Copy and pastle. Ja to využívam strašne moc, a strašne veľakrát som a tento zlozvyk doplatil. To neboli minúty, alebo hodiny odstraňovania chýb týmto spôsobených. Raz som hľadal chybu 3 týždne a zistil som že som skopíroval zlé slovíčko... Naučiť sa prstoklad by mi trvalo menej. Len tým chcem povedať, že neodporúčam nikomu používať tento spôsob.
Vytvorím si nový script v programe powerGUI.
Potrebujem získať dokument, lenže funkcia sleep nieje dostatočná. Potrebujem ju zabezpečiť, proti pomalému načítaniu stránky. Hľadám teda niečo ako onModuleLoad
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate("http://kreveta.net/")
$ie //prehľadávam výpis, nič tam nieje
$ie |Get-Member // ani tu, akurát readystate
$ie.ReadyState //4 , to sa mi zíde neskôr
$ie.Document // vo výpise nachádzam onreadystatechange, to by som potreboval
//zatváram prehliadač z krevetou
$ie // prazdny výpis
$ie.Document //nič
$ie = new-object -com "InternetExplorer.Application" //vytváram nový prázdny browser
$ie.Document // nič, to nieje dobre
$ie.Document|Get-Member //error. prázdnemu dokumentu nemôžem nastaviť onreadystatechange, hľadám ďalej
$ie|Get-Member // vo výpise nič užitočné
$ie.navigate("http://kreveta.net/")
$ie.Document //zadal som dva riadky naraz. možno sa po volaní stránky vytvorí prázdny dokument. ale bohužiaľ
$ie.Document // naplní sa až po kompletnom načítaní stránky
$ie.navigate("http://kreveta.net/")
$ie //prehľadávam výpis, nič tam nieje
$ie |Get-Member // ani tu, akurát readystate
$ie.ReadyState //4 , to sa mi zíde neskôr
$ie.Document // vo výpise nachádzam onreadystatechange, to by som potreboval
//zatváram prehliadač z krevetou
$ie // prazdny výpis
$ie.Document //nič
$ie = new-object -com "InternetExplorer.Application" //vytváram nový prázdny browser
$ie.Document // nič, to nieje dobre
$ie.Document|Get-Member //error. prázdnemu dokumentu nemôžem nastaviť onreadystatechange, hľadám ďalej
$ie|Get-Member // vo výpise nič užitočné
$ie.navigate("http://kreveta.net/")
$ie.Document //zadal som dva riadky naraz. možno sa po volaní stránky vytvorí prázdny dokument. ale bohužiaľ
$ie.Document // naplní sa až po kompletnom načítaní stránky
skúsim to teda pomocou pôvodného sleep. Vytvorím si prázdny script, napíšem doňho smyčku while a skopírujem všetko priamo do novej konzole.
PS C:> $ie = new-object -com "InternetExplorer.Application"
PS C:> $ie.navigate("http://kreveta.net/")
PS C:> while (!$ie.Document){
>> Start-Sleep -m 300
>> }
>> echo "end"
>>
PS C:> $ie.navigate("http://kreveta.net/")
PS C:> while (!$ie.Document){
>> Start-Sleep -m 300
>> }
>> echo "end"
>>
Takto to nepôjde. Smyčku mi nezoberie hneď , ale až po stlačení enteru. Skúsim to dať do funkcie, to určite pôjde. Otváram môj starší článok. Hľadám syntax a funkcie argumetu.
Pôvodný script prepisujem na :
function conectPage
{param ($Name)
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate($Name)
while (!$ie.Document){
Start-Sleep -m 300
}
return($ie.Document)
}
$document=conectPage("http://kreveta.net/")
$document
{param ($Name)
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate($Name)
while (!$ie.Document){
Start-Sleep -m 300
}
return($ie.Document)
}
$document=conectPage("http://kreveta.net/")
$document
Funguje. výsledkom je načítaný dokument.
Teraz potrebujem vytiahnuť zo stránky potrebný text. Otvorím si chrome, stlačím klávesovú skratku Ctrl+Shift+I. Zobrazím si štruktúru HTML. Podľa nej získavam prístup k textu. Zaujímajú ma nadpisy článkov, čas a autor.
$document.childNodes.item(1) // výpis podla očakávaní
$HTMLElement = $doc.childNodes.item(1) // error, zle som skopíroval
$HTMLElement =$document.childNodes.item(1)
$BODYElement = $HTMLElement.childNodes.item(1)
$BODYElement.tagName //BODY
$BODYElement.childNodes.item(0).class //z HTML na krevete som zistil že obsah je v prvom dive z className "obvod", nič mi nevypísalo
$BODYElement.childNodes.item(0).className //nič
$BODYElement.childNodes.item(0).tagName //DIV, to sedí. idem do w3c definicie a hľadám prístup k class cez element DIV
//našiel som len className, to nefungovalo už predtým, skúšam teda
$BODYElement.childNodes.item(0)|get-Member //prehľadávam výpis, nič použiteľné
$BODYElement.childNodes.item(0) //nič nenachádzam, akurát atributes.
$BODYElement.childNodes.item(0).atributes//tak to som nemal robiť. No Class name mi zatiaľ netreba. Idem teda ďalej
clear
$obvod=$BODYElement.childNodes.item(0)
$obvod.childNodes.item(5).tagname //nič
$obvod.childNodes.item(5).tagName //nič, niekde je chyba
$obvod // chyba, namiesto obvodu mám hlavičku
$BODYElement.childNodes.length //2
$BODYElement.childNodes.item(0) //v texte je prvý div hlavička, musí to byť správne
$obvod=$BODYElement.childNodes.item(0)
$obvod.childNodes.item(5) // ahh, bolo to správne :-D
$BIGLEFTElement=$obvod.childNodes.item(5)
RIGHTPARTElement=$BIGLEFTElement.childNodes.item(1) //eroor, prečo ?? no jasne, znak $
$RIGHTPARTElement=$BIGLEFTElement.childNodes.item(1) //error, ahh
$BIGLEFTElement
$BIGLEFTElement.childNodes.length //0, ahha,
$obvod.childNodes.length //9, ja som ich napočítal len 8
$obvod.childNodes//kontrolujem, už viem. ja som sa riadil podla innerHTML, mal som pozerať na outerHTML.
$obvod=$BODYElement.childNodes.item(0) //musím íst znova, toto je obvod
$obvod.childNodes.length //9
clear
$obvod.childNodes// počítam, je šieste v poradí
$BIGLEFTElement=$obvod.childNodes.item(6)
$BIGLEFTElement //outerHTML pasuje
$BIGLEFTElement.childNodes.length //3 pasuje
$RIGHTPARTElement = $BIGLEFTElement.childNodes.item(1)
$RIGHTPARTElement.childNodes.length //2, pasuje. prvý je paginátor, druhý je obsah
$OBSAHElement = $RIGHTPARTElement.childNodes.item(1)
$OBSAHElement.childNodes.length //0, zle čosi
$OBSAHElement.tagName// no jasne. v chrome sa nezobrazujú tagy br
clear
$RIGHTPARTElement.childNodes //hladam obsah, je hned prvý
$OBSAHElement = $RIGHTPARTElement.childNodes.item(0)
$HTMLElement = $doc.childNodes.item(1) // error, zle som skopíroval
$HTMLElement =$document.childNodes.item(1)
$BODYElement = $HTMLElement.childNodes.item(1)
$BODYElement.tagName //BODY
$BODYElement.childNodes.item(0).class //z HTML na krevete som zistil že obsah je v prvom dive z className "obvod", nič mi nevypísalo
$BODYElement.childNodes.item(0).className //nič
$BODYElement.childNodes.item(0).tagName //DIV, to sedí. idem do w3c definicie a hľadám prístup k class cez element DIV
//našiel som len className, to nefungovalo už predtým, skúšam teda
$BODYElement.childNodes.item(0)|get-Member //prehľadávam výpis, nič použiteľné
$BODYElement.childNodes.item(0) //nič nenachádzam, akurát atributes.
$BODYElement.childNodes.item(0).atributes//tak to som nemal robiť. No Class name mi zatiaľ netreba. Idem teda ďalej
clear
$obvod=$BODYElement.childNodes.item(0)
$obvod.childNodes.item(5).tagname //nič
$obvod.childNodes.item(5).tagName //nič, niekde je chyba
$obvod // chyba, namiesto obvodu mám hlavičku
$BODYElement.childNodes.length //2
$BODYElement.childNodes.item(0) //v texte je prvý div hlavička, musí to byť správne
$obvod=$BODYElement.childNodes.item(0)
$obvod.childNodes.item(5) // ahh, bolo to správne :-D
$BIGLEFTElement=$obvod.childNodes.item(5)
RIGHTPARTElement=$BIGLEFTElement.childNodes.item(1) //eroor, prečo ?? no jasne, znak $
$RIGHTPARTElement=$BIGLEFTElement.childNodes.item(1) //error, ahh
$BIGLEFTElement
$BIGLEFTElement.childNodes.length //0, ahha,
$obvod.childNodes.length //9, ja som ich napočítal len 8
$obvod.childNodes//kontrolujem, už viem. ja som sa riadil podla innerHTML, mal som pozerať na outerHTML.
$obvod=$BODYElement.childNodes.item(0) //musím íst znova, toto je obvod
$obvod.childNodes.length //9
clear
$obvod.childNodes// počítam, je šieste v poradí
$BIGLEFTElement=$obvod.childNodes.item(6)
$BIGLEFTElement //outerHTML pasuje
$BIGLEFTElement.childNodes.length //3 pasuje
$RIGHTPARTElement = $BIGLEFTElement.childNodes.item(1)
$RIGHTPARTElement.childNodes.length //2, pasuje. prvý je paginátor, druhý je obsah
$OBSAHElement = $RIGHTPARTElement.childNodes.item(1)
$OBSAHElement.childNodes.length //0, zle čosi
$OBSAHElement.tagName// no jasne. v chrome sa nezobrazujú tagy br
clear
$RIGHTPARTElement.childNodes //hladam obsah, je hned prvý
$OBSAHElement = $RIGHTPARTElement.childNodes.item(0)
V obsahu už je presne to čo sme hľadali. Každý príspevok má 6 elementov div. Zabudol som na začiatku tejto časti povedať, že si musím prepisovať výsledky. Teraz ich už v konzole nenájdem. Ja som ich však zapisoval tu, do článku a tak ich mám po ruke. Môžem to teda nijak uceliť do pôvodného scriptu z funkciou na otvorenie dokumentu. Po zapísaní mi ostalo:
function conectPage
{param ($Name)
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate($Name)
while (!$ie.Document){
Start-Sleep -m 300
}
return($ie.Document)
}
$document=conectPage("http://kreveta.net/")
#toto si uložím, určite sa mi to niekedy zíde
#$HTMLElement =$document.childNodes.item(1)
#$BODYElement = $HTMLElement.childNodes.item(1)
#$OBVODElement=$BODYElement.childNodes.item(0)
#$BIGLEFTElement=$OBVODElement.childNodes.item(6)
#$RIGHTPARTElement = $BIGLEFTElement.childNodes.item(1)
#$OBSAHElement = $RIGHTPARTElement.childNodes.item(0)
$obsahNodes = $document.childNodes.item(1).childNodes.item(1).childNodes.item(0).childNodes.item(6).childNodes.item(1).childNodes.item(0).childNodes
{param ($Name)
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate($Name)
while (!$ie.Document){
Start-Sleep -m 300
}
return($ie.Document)
}
$document=conectPage("http://kreveta.net/")
#toto si uložím, určite sa mi to niekedy zíde
#$HTMLElement =$document.childNodes.item(1)
#$BODYElement = $HTMLElement.childNodes.item(1)
#$OBVODElement=$BODYElement.childNodes.item(0)
#$BIGLEFTElement=$OBVODElement.childNodes.item(6)
#$RIGHTPARTElement = $BIGLEFTElement.childNodes.item(1)
#$OBSAHElement = $RIGHTPARTElement.childNodes.item(0)
$obsahNodes = $document.childNodes.item(1).childNodes.item(1).childNodes.item(0).childNodes.item(6).childNodes.item(1).childNodes.item(0).childNodes
Teraz mi to treba už len zobraziť. Myslím si však, že tento článok už dávno presiahol normál, takže vám prajem príjemnú zábavu a silné nervy.
Taký urýchlený výsledok je možné pozrieť po spustení tohto kódu :
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
function conectPage
{param ($Name)
$ie = new-object -com "InternetExplorer.Application" -Property @{visible=0}
$ie.navigate($Name)
while (!$ie.Document){
Start-Sleep -m 300
}
return($ie.Document)
}
function openPage
{param ($sender, $eventArgs)
}
function showInfo
{param ($levyadmin)
$LINK = $levyadmin.childNodes.item(0).childNodes.item(0).childNodes.item(0).href
$NADPIS = $levyadmin.childNodes.item(0).childNodes.item(0).childNodes.item(0).childNodes.item(0).innerText
$AUTOR = $levyadmin.childNodes.item(1).childNodes.item(0).innerText
$DATUM = $levyadmin.childNodes.item(2).childNodes.item(0).innerText
$objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon
$objNotifyIcon.Icon = "je treba nastavit absolutnu cestu k niejakej ikone"
$objNotifyIcon.BalloonTipIcon = "Info"
$objNotifyIcon.BalloonTipTitle = $NADPIS
$objNotifyIcon.BalloonTipText = $AUTOR + " " + $DATUM
$objNotifyIcon.Visible = $True
$objNotifyIcon.ShowBalloonTip(3000)
}
$document=conectPage("http://kreveta.net/")
$obsahNodes = $document.childNodes.item(1).childNodes.item(1).childNodes.item(0).childNodes.item(6).childNodes.item(1).childNodes.item(0).childNodes
for ($e=0;$e -lt 40;$e+=7){
showInfo($obsahNodes.item($e))
}
function conectPage
{param ($Name)
$ie = new-object -com "InternetExplorer.Application" -Property @{visible=0}
$ie.navigate($Name)
while (!$ie.Document){
Start-Sleep -m 300
}
return($ie.Document)
}
function openPage
{param ($sender, $eventArgs)
}
function showInfo
{param ($levyadmin)
$LINK = $levyadmin.childNodes.item(0).childNodes.item(0).childNodes.item(0).href
$NADPIS = $levyadmin.childNodes.item(0).childNodes.item(0).childNodes.item(0).childNodes.item(0).innerText
$AUTOR = $levyadmin.childNodes.item(1).childNodes.item(0).innerText
$DATUM = $levyadmin.childNodes.item(2).childNodes.item(0).innerText
$objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon
$objNotifyIcon.Icon = "je treba nastavit absolutnu cestu k niejakej ikone"
$objNotifyIcon.BalloonTipIcon = "Info"
$objNotifyIcon.BalloonTipTitle = $NADPIS
$objNotifyIcon.BalloonTipText = $AUTOR + " " + $DATUM
$objNotifyIcon.Visible = $True
$objNotifyIcon.ShowBalloonTip(3000)
}
$document=conectPage("http://kreveta.net/")
$obsahNodes = $document.childNodes.item(1).childNodes.item(1).childNodes.item(0).childNodes.item(6).childNodes.item(1).childNodes.item(0).childNodes
for ($e=0;$e -lt 40;$e+=7){
showInfo($obsahNodes.item($e))
}
Prosím o vyjadrenie svojho názoru na článok komentárom, alebo pridaním Líbí/Nelíbí.
Komentáře
Přidat nový
Pro přispívání musíte být přihlášen



