Browser mit PHP fernsteuern
Heute will ich mal erklären wie ich mit PHP (und natürlich noch weiteren Hilfsmitteln) meinen Browser fernsteuern kann. Das kann ganz nützlich sein, wenn man Workflows automatisieren will und dies dann mit PHP triggern möchte. Euch fallen bestimmt noch andere Schweinereien ein, die man damit machen kann. Wir wollen hier und heute nur die technische Grundlage legen.
Ich habe ja gerade schon angekündigt, dass wir noch außer PHP andere Tools benötigen. Natürlich ist Selenium, die Browser-Allzweckwaffe eines davon. PHPUnit (zumindest Teile davon) werden wir auch noch verwenden. Zuerst mal brauchen wir eine Instanz des Selenium Remote Control auf einem PC installiert, der den Browser beheimatet, den wir fernsteuern wollen. Als nächstes schnappen wir uns das PHPUnit Paket und da eigentlich nur den SeleniumDriver (sollte bei neueren PHPUnit Versionen vorhanden sein). Jetzt kann es eigentlich schon losgehen. Wir brauchen jetzt nur eine Instanz des Treibers, diesen müssen wir noch konfigurieren und dann können wir schon loslegen und das in fast der ganzen Mächtigkeit wie es Selenium kann.
$selenium = new PHPUnit_Extensions_SeleniumTestCase_Driver( );
$selenium->setBrowser( '*firefox' );
$selenium->setHost( '<IP des Selenium RC>' );
$selenium->setBrowserUrl( 'http://www.example.com' );
$selenium->start( );
...
$selenium->stop( );
Da müsste eigentlich schon alles sein. Die drei Punkte können wir jetzt ersetzen mit den Dingen die wir tatsächlich tun wollen. Das einfachste wäre zum Beispiel eine Seite aufzumachen, auf einen Link zu klicken und danach einen Screenshot zu machen. Das würde dann zum Beispiel so aussehen:
$selenium->open( '/index.php' );
$selenium->click( 'link=Impressum' );
$selenium->captureEntirePageScreenshot( 'screenshot.png' );
Wenn ihr auch nicht sicher seid, welche Befehle Selenium so beherrscht, dann schaut euch entweder mal die Treiberklasse an oder spiel ein wenig mit dem Selenium Firefox Plugin rum. Wenn ihr dort nämlich einen Export nach PHP macht, dann habt ihr schon die meisten Befehle gesehen. In den meisten der Fälle ist es eh nur ein 1:1 Mapping.
Jetzt muss ich erstmal in Deckung gehen, bevor ich weiterschreibe … einen Moment … so in Sicherheit. Und zwar habe ich den Code, den ihr oben findet noch nicht getestet, da ich auf dem System, dass ich gerade verwende, noch eine alter Version von PHPUnit drauf habe und das im Moment auch nicht ändern kann. Vielleicht spielt heute noch ein wenig Faulheit rein, aber auf jeden Fall gebe ich keine Garantie, dass alles was ich als Code stehen habe auch klappt. Wer Interesse an dem alten PHPUnit Ansatz hat, dem schicke ich natürlich gerne auch den alten (funktionierenden) Code zu. Aber eigentlich bin ich mir ziemlich sicher, dass es klappen wird, denn außer der Auslagerung des Treibers hat sich nicht viel geändert.
Ach ja, versprochen, dass dieses blinde Programmieren nicht häufig vorkommen wird.
Sehr schöner Artikel 🙂 Mit Selenium habe ich mich noch garnicht befasst, aber das liest sich sehr interessant und macht Lust auf mehr 😉
„Beware of bugs in the above code; I have only proved it correct, not tried it.“ – Donald Knuth
@Schaelle: Nettes Zitat 🙂
Man gibt ja eine IP des „Browser-PCs“ an. Mal angenommen das ist jetzt nicht der localhost.
Über welchen Port kommuniziert denn (in diesem Fall) der Selenium Treiber für PHP mit dem Browser?
Und wie authentifiziert er sich? Ich mein da könnte ja jeder kommen 😉
Und kann man diese Verbindung auch verschlüsseln? 😉
Ok, ich hab mal in den Code der PHPUnit-Class geguckt…
Der Port is per default 4444 und lässt sich per setPort($port) ändern.
Aber einen Authentifizierungs-Mechanismus konnte ich im Code nicht entdecken. Da wird eine URL zusammengebaut:
$url=http://HOST:PORT/selenium-server/driver/?cmd=COMMAND
Und diese dann per fopen($url,’r‘) aufgerufen.
Aber es kann ja nicht sein, dass ich einen fernsteuerbaren Browser ohne Authentifizierung ins Netz stellen muss?
Kann ich dem Server dann wenigstens sagen, welche Client-IPs Anforderungen stellen dürfen, ähnlich wie bei Apache (Disallow: *, Allow: my_client.de)?
@Christopher: Ja kannst Du, nennt sich Firewall Regel 😉
Übrigens, prima Beitrag. Man kommt kaum nach, alles auszuprobieren was Du hier an tollen Inspirationen postest Nils, Danke!
lol. Manchmal kommt man auf die simpelsten Sachen nicht 😉