Blog

Leren programmeren automatiseren

Ik heb lang getwijfeld over dit blog, voor de beste uitleg zou ik jullie namelijk mee willen nemen in de wereld van autohotkey (https://www.autohotkey.com/) dat is een programma waarmee je op Windows heel makkelijk een heleboel dingen kan automatiseren. Het gebruikt echter zijn eigen programmeer taal, en ik doe mijn best om al het programmeren dat ik samen met jullie doe, in javascript te doen, zodat jullie makkelijk mee kunnen blijven doen. Een aardige uitleg waarom ik jullie autohotkey wilde laten zien en waarom ik het niet heb gedaan, is dit filmpje van Tom Scott.

Een nadeel van javascript voor het uitleggen van automatisering is dat je browser veilig is gemaakt. Elke keer dat je naar een andere pagina gaat  wordt je console opnieuw gestart. Dat is maar goed ook, want als dat niet zou gebeuren zou je daar vreselijk misbruik van kunnen maken. Maar dat betekent dus dat je alleen maar dingen in je browser kunt automatiseren die binnen hetzelfde scherm gebeuren. Wat je dan nog wel kunt doen is data van een andere website ophalen via een API en dat vervolgens gebruiken tijdens je automatisering. Dus mocht je straks de smaak te pakken hebben, pak mijn vorige blog er nog een keer bij.

Maar laten we iets simpeler beginnen. Het idee van iets automatiseren is dat je een taak die saai is of die je vaak moet doen, door de computer kan laten doen. Dat klinkt heel aanlokkelijk, maar het is niet altijd de moeite waard. Xkcd heeft een tabel waarin je kunt opzoeken of het zinvol is om iets te optimaliseren door het te automatiseren:  (bron: xkcd.com)

Is It Worth the Time?

Als je er dan ook nog een andere xkcd bij pakt over automatiseren schetst dat een plaatje waarin het automatiseren van taken niet altijd de heilige graal is die het soms lijkt te zijn:

Image result for xkcd automation

Dat neemt niet weg dat je soms door iets te automatiseren enorm veel werk door een computer kan laten doen in plaats van mensen, of de computer taken kan laten doen waar je zelf eigenlijk geen zin in hebt. Uit ervaring blijkt dat totaal fictieve onrealistische voorbeelden vaak het beste zijn, het zet de lezer namelijk aan tot zelf een realistisch scenario te bedenken. Bovendien is het voor mij het minste werk en dat is toch een beetje waar dit blog over gaat. Dus we doen een raar hypothetisch voorbeeld.

Stel je doet een online survey over een video en om te zorgen dat je de video blijft kijken en dat je niet bij je computer wegloopt moet je van de website elke 20 seconden op een knop drukken, dat reset een timer,als die timer niet op tijd gereset wordt is je aandacht er schijnbaar niet genoeg bij en krijg je niet betaald. De ethische oplossing is elke 20 seconden op de knop drukken, de makkelijkste manier, automatiseer het drukken op de knop. Hier is de site: https://undercover.horse/automatiseren/resettimer.htm

Het automatiseren van deze taak is vrij eenvoudig. Wat we willen doen is  elke X seconde op de knop drukken, omdat te doen moeten we eerst weten hoe de knop heet, daarvoor kijken we naar de broncode van de site. Daarin vinden we:

<button id="btn" onclick="set20()">reset de timer</button>

Dat is makkelijk, de knop heeft een id attribuut. Javascript heeft een manier om een object te selecteren bij zijn id:

document.getElementById()

We geven het id “btn” mee en dan gebruiken we de click functie om er op te  klikken:

document.getElementById("btn").click()

Dat is 1 klik, we willen het echter elke X seconden, omdat te doen kunnen we er een interval van maken:

setInterval('document.getElementById("btn").click()',5000);

Deze code zorgt er voor dat er elke 5000 milliseconden (gelijk aan 5 seconden) op de knop wordt geklikt. Als je dat in je console plakt ben je klaar, de timer komt niet meer voorbij 15.

Dit is een truc die je op elke pagina toe kan passen die een knop heeft waar je op moet klikken die niet de hele pagina ververst. Ander voorbeeld: stel je voor je wilt een kaartje kopen, om dat te doen moet je op de bestelknop op een pagina klikken. Deze wordt echter pas klikbaar op een bepaald moment. Je kan geduldig op de site wachten en toeslaan zodra de knop beschikbaar wordt, of je blijft er constant op klikken en loopt er bij weg. Hier is een demo pagina: https://undercover.horse/automatiseren/klikzsm.htm

Kleine tegenvaller, als we naar de knop kijken zien we dat hij geen id heeft:

setInterval('document.getElementById("btn").click()',5);

Dat is echter makkelijk op te lossen, als je in je console zit kan je naar het tabblad elements waar je de html van de pagina ziet staan. Als je vervolgens met je rechtermuisknop op de html code van de button klikt, kan je kiezen voor “edit as HTML” en dan kan je er zelf gewoon id=”btn” bij zetten. (Je moet buiten het edit-blokje klikken om het te bevestigen) Omdat we zo snel mogelijk willen zijn zetten we de interval waarde wat lager:

setInterval('document.getElementById("btn").click()',5);

Nu gebeurt het elke 5 milliseconden, daar kan je zelf nooit tegenop klikken. In het huidige voorbeeld is het alleen wel zo dat je al die acties binnen 20 seconden moet doen anders is de knop al beschikbaar. Als alternatief kan je ook de knop zoeken door alle knoppen te zoeken en dan de eerste uit de lijst te kiezen:

setInterval('document.getElementsByTagName("button")[0].click()',5);

Het klikken op een knop is handig, maar vaak moet je meer op een pagina doen dan alleen een knop indrukken. Gelukkig kan je met javascript een heleboel van die dingen gewoon doen. Neem bijvoorbeeld een pagina met  een formulier zoals deze: https://undercover.horse/automatiseren/formulier.htm

Stel we willen blauw een heel aantal keer kiezen. Dan kunnen we het formulier een aantal keer achter elkaar invullen. Of we automatiseren het:

let y = function () {
  document.getElementsByTagName("input")[0].value = "Daan";
  document.getElementsByTagName("input")[1].value = "Veraart";
  document.getElementsByTagName("input")[4].checked = true;
  document.getElementsByTagName("button")[0].click();
}
setInterval(y, 100);

Dit lijkt allemaal vrij triviaal, maar dit zijn dan ook nog maar hele simpele voorbeelden, die je allemaal in je browser kunt uitvoeren. De essentie is echter dat je een taak opsplitst in kleine subtaakjes en dan kijkt of je die met een stukje code kan oplossen. Dat is iets wat je bij programmeren eigenlijk heel vaak gebruikt. Alleen dan in de vorm van helper functies. Als je en stuk code meerdere keren in je applicatie hebt staan, dan kan je beter van dat stuk code een functie maken. Elke keer dat je dan dat stuk code nodig hebt, automatiseer je dat door in plaats van dat stuk code te typen, de functie aan te roepen. Bijkomend voordeel is dat als je iets aanpast in dat stuk code, het meteen op alle plekken in je programma aangepast is.

Het leukste van iets automatiseren is kijken hoe de computer voor je aan het werk is. Zo heb ik laatst het verplaatsten van Vimeofilmpjes naar Youtube geautomatiseerd. Als je het dan opstart (de foutmelding oplost waar je tegenaan loopt (voor degene die het filmpje van Tom Scott hebben gezien, het was een beetje een bodge) en nog een keer opstart) en je ziet dat hij logregel voor logregel braaf bezig is, en dan op Youtube het filmpje ziet verschijnen met dezelfde titel en omschrijving als dat het op Vimeo heeft, dat geeft een voldaan gevoel. Het is wel een klein beetje zonde dat we de tijd die we gewonnen hebben met automatiseren besteden aan het kijken naar hoe de computer het werkt doet, die hadden we beter kunnen besteden aan het uitleggen van drie waarde logica… Misschien moet ik dat maar eens proberen te automatiseren. 

Back-To-Top