Seite 1 von 2
Javascript ausführen
Verfasst: Sonntag 1. November 2009, 00:58
von cryzed
Ich suche eine Möglichkeit einen JavaScript Interpreter mit Python zu benutzen. Z.b. hole ich mir den Quelltext einer bestimmten Webseite die JavaScript benutzt (um z.B. intern beim Laden 20 Zeilen HTML Quelltext erzeugt und hinzufügt) und möchte diesen String (den Quelltext) dann einfach mit dem Interpreter ausführen und die veränderte Seite als String zurückbekommen.
Ich kenne bereits
python-spidermonkey, aber das scheint mir noch etwas unausgereift bzw. nichts das zu können was ich eigentlich suche - oder übersehe ich das nur?
Kennt jemand so etwas in die Richtung? Wäre klasse.
Re: Javascript ausführen
Verfasst: Sonntag 1. November 2009, 08:25
von gerold
cryzed hat geschrieben:Quelltext einer bestimmten Webseite
Hallo cryzed!
Leider, so etwas kenne ich nicht. Das ist eine der schweren Aufgaben, die heutzutage ein Browser erfüllen muss.
Ich weiß nur, dass mir der Firefox mit der Firebug-Erweiterung den generierten Quelltext anzeigen kann. Die "Web Developer" Toolbar kann das auch.
Wenn ich es nicht allzuoft brauche, dann würde ich den generierten Quellcode der HTML-Seite mit diesen Tools manuell auslesen.
Wenn ich es öfter brauchen würde, dann würde ich mir evt. eine eigene Firefox-Erweiterung mit JavaScript und XUL
https://developer.mozilla.org/de/XUL_Tutorial schreiben.
Vielleicht könnte man den Firefox und Python kombinieren. Vielleicht lässt sich von Python aus, der Firefox mit einer "crome://"-URL (Adresse einer Firefox-Erweiterung) starten. Und vielleicht kann so eine Firefox-Erweiterung auch ins Dateisystem oder nach STDOUT schreiben. Wenn das ginge, dann könnte man...

Aber ich weiß es nicht.
mfg
Gerold

Verfasst: Sonntag 1. November 2009, 08:35
von lunar
@cryzed: Ein einfacher Javascript-Interpreter reicht nicht. Du benötigst eine letztlich vollwertige Browser-Engine, die in der Lage ist, HTML zu parsen, in einen DOM-Baum zu übersetzen und Javascript-Operationen mit diesem Baum auszuführen.
Die einfachste, mir bekannte Möglichkeit ist QtWebkit aus PyQt4. Ob diese Abhängigkeit gerechtfertigt ist, musst Du selbst entscheiden.
Verfasst: Sonntag 1. November 2009, 08:41
von gerold
Hallo cryzed!
Mir ist noch etwas eingefallen.
Von JavaScript/XUL aus, kann man vielleicht nicht auf das Dateisystem zugreifen. Leider konnte ich noch nichts darüber finden (zumindest nichts Konkretes). Aber eines funktioniert sicher. Du kannst von JavaScript aus einen HTTP-Request senden. Somit genügt es, wenn du mit Python z.B. als XMLRPC-Server auf einen Request wartest.
So langsam beginnt die Firefox-Einbindung in meinem Hirn Gestalt anzunehmen.
Mit
http://pypi.python.org/pypi/mozrunner/ kann man den Firefox ein wenig in die richtige Richtung lenken.
mfg
Gerold
PS:
http://www.captain.at/programming/xul/
PS2:
https://developer.mozilla.org/en/XUL_Tu ... Interfaces (Speichern funktioniert also doch)
Verfasst: Sonntag 1. November 2009, 09:09
von nemomuk
Naja, was noch möglich wäre, ist Selenium zu verwenden und dann einfach den Quelltext ausgeben lassen - das scheint mir am einfachsten zu funktionieren.
Verfasst: Sonntag 1. November 2009, 09:25
von gerold
SchneiderWeisse hat geschrieben:Naja, was noch möglich wäre, ist Selenium zu verwenden und dann einfach den Quelltext ausgeben lassen - das scheint mir am einfachsten zu funktionieren.
Hallo SchneiderWeisse!
Schöne Idee! Gefällt mir.

Das ist auf jeden Fall sehr viel einfacher zu realisieren als meine Idee mit XUL/JavaScript.
mfg
Gerold

Verfasst: Sonntag 1. November 2009, 11:30
von Leonidas
Gerold, JavaScript gibt es in verschiedenen Kontexten. Der üblichste ist JavaScript in einer Webseite, bei dem der Code in einer Sandbox läuft in der der Code nicht schreiben kann oder bei dem XmlHttpRequests (AJAX) auf die eigene Domain eingeschränkt sind (Same Origin Policy). Daneben gibt es in Firefox auch noch den Chrome-Kontext, denn Firefox besteht kurioserweise aus einem Haufen JavaScript-Code der von XULRunner ausgeführt wird, und einen Browser bildet. Statt auf dem DOM-Tree von HTML zu arbeiten, wird dort am DOM-Tree von XUL gearbeitet. In diesem Kontext kann JavaScript auch auf die Festplatte schreiben, in diesem Kontext laufen auch die Firefox-Plugins. Der dritte Kontext ist ein Standalone-Interpreter wie Seed oder GJS, die mit HTML schon nichts mehr zu tun haben und auf der gleichen Stufe stehen wie CPython.
Verfasst: Sonntag 1. November 2009, 11:48
von gerold
Leonidas hat geschrieben:Gerold, JavaScript gibt es in verschiedenen Kontexten
Hallo Leonidas!
Ich wusste nur nicht genau (Hinweise hatte ich bereits gefunden), wie einfach/schwierig es ist, mit einem installierten Firefox-Addin auf die Festplatte zu schreiben. Falls es schwer oder unmöglich gewesen wäre, hätte man es auf Umwegen über AJAX machen können. Aber wie ich kurz später feststellen konnte, ist es ohne (große) Probleme möglich, aus einem Firefox-Addin heraus auf die Festplatte zu schreiben, was ich mit Links zu Erklärungen bewiesen habe.
Mich deshalb über JavaScript aufzuklären halte ich für etwas übertrieben.

Es kränkt mich sogar etwas.
lg
Gerold

Verfasst: Sonntag 1. November 2009, 12:07
von cryzed
Wow, Danke für die vielen Antworten!
Das mit dem XMLRPC Server hört sich interessant an. Ich könnte als mein Python script laufen lassen und dann z.B. mit Greasemonkey, nachdem die besuchte Webseite fertig geladen ist, den Quelltext als String an die XMLRPC Instanz senden und dann im Python Script darauf reagieren - die Idee an sich ist genial, nur leider hätte ich dann Firefox als große (und programmatisch) langsame Abhängigkeit. Wenn man nämlich mal einen Schritt weiterdenkt und sowas programmatisch machen möchte, sprich "Rufe Seite 1-10 auf und schick sie an den XMLRPC Server" müsste ich z.B. mit webbrowser.open() arbeiten um diesen Vorgang zu automatisieren. Auf den Vorschlag mit Selenium trifft das gleiche zu.
Was jetzt noch übrigt bleibt ist das QtWebkit und das Schreiben eines eigenes Addons. Beim Schreiben des eigenen Addons das mir z.B. den Quelltext der Seite auch an den XMLRPC Server sendet oder auf die Fesplatte schreibt ist wieder das Problem das ich Firefox benutzen muss um sowas zu automatisieren; Sprich: Ich habe die ganze Zeit eine Firefox-Instanz laufen.
Ich denke ich werde mich dann mal genauer mit dem QtWebkit befassen, vielen Dank nochmal für all die Antworten!
Verfasst: Sonntag 1. November 2009, 12:27
von Dav1d
ich kenn mich da echt wenig aus, aber was ist mit einer JS-Engine z.B. die von Chrome:
http://code.google.com/p/v8/w/list
oder geht das nicht?
Verfasst: Sonntag 1. November 2009, 12:36
von Leonidas
gerold hat geschrieben:Mich deshalb über JavaScript aufzuklären halte ich für etwas übertrieben.

Es kränkt mich sogar etwas.
Oh, tut mir leid. Das hab ich nicht beabsichtigt.
Ich wusste nur nicht, wie viel du mit XUL/JavaScript außerhalb des Browsers schon gemacht hast, daher hab ich einfach mal mehr geschrieben.
Verfasst: Sonntag 1. November 2009, 14:00
von cryzed
Ich glaube nicht das das so einfach geht. Die V8 Engine wird sicher nicht die Möglichkeit haben den DOM Tree zu manipulieren sondern kann nur puren JavaScript Code ausführen (so habe ich das auf jeden Fall verstanden).
Etwas Interessantes was ich zu dem Thema noch entdeckt habe wäre
DOMForm, scheint aber sehr outdated da sogar noch die Python Version 2.3 referenziert wird. Mit ein bisschen Glück entscheidet sich der Entwickler von
mechanize in dem nächsten Release ja dafür etwas JavaScript Unterstützung hinzuzufügen, weil genau damit will ich die JavaScript Unterstützung ja benutzen.
Verfasst: Sonntag 1. November 2009, 14:03
von snafu
cryzed hat geschrieben:Etwas Interessantes was ich zu dem Thema noch entdeckt habe wäre
DOMForm, scheint aber sehr outdated da sogar noch die Python Version 2.3 referenziert wird.
Ich meine sogar, das schon mal ausprobiert zu haben als ich vor dem selben Problem stand wie du jetzt. Und es ging nicht.
cryzed hat geschrieben:Mit ein bisschen Glück entscheidet sich der Entwickler von
mechanize in dem nächsten Release ja dafür etwas JavaScript Unterstützung hinzuzufügen, weil genau damit will ich die JavaScript Unterstützung ja benutzen.
Das wage ich zu bezweifeln. Ansonsten versuche den Entwickler über
die Mailinglist für Mechanize zu kontaktieren.
Verfasst: Sonntag 1. November 2009, 14:37
von cryzed
snafu hat geschrieben:cryzed hat geschrieben:Etwas Interessantes was ich zu dem Thema noch entdeckt habe wäre
DOMForm, scheint aber sehr outdated da sogar noch die Python Version 2.3 referenziert wird.
Ich meine sogar, das schon mal ausprobiert zu haben als ich vor dem selben Problem stand wie du jetzt. Und es ging nicht.
cryzed hat geschrieben:Mit ein bisschen Glück entscheidet sich der Entwickler von
mechanize in dem nächsten Release ja dafür etwas JavaScript Unterstützung hinzuzufügen, weil genau damit will ich die JavaScript Unterstützung ja benutzen.
Das wage ich zu bezweifeln. Ansonsten versuche den Entwickler über
die Mailinglist für Mechanize zu kontaktieren.
Danke, werde ich demnächst tun!
Verfasst: Sonntag 1. November 2009, 16:08
von nemomuk
Verstehe nicht, was gegen Selenium spricht? Beliebiger Browser + selenium-server, der Rest lässt sich in 10 Zeilen Code erledigen. Man muss die Welt ja nicht neu erfinden.
Verfasst: Sonntag 1. November 2009, 20:48
von cryzed
SchneiderWeisse hat geschrieben:Verstehe nicht, was gegen Selenium spricht? Beliebiger Browser + selenium-server, der Rest lässt sich in 10 Zeilen Code erledigen. Man muss die Welt ja nicht neu erfinden.
Der Browser ist das Problem. Angenommen ich möchte 10 Seiten abrufen, das JavaScript interpretieren und dann auswerten dann müsste der Browser auch an sich 10 Seiten aufrufen - was viel langsamer und umständlicher ist. Oder verstehe ich dich falsch?
Verfasst: Montag 2. November 2009, 05:46
von snafu
Ja, für den Quelltext von zehn verschiedenen Seiten, so wie sie der Benutzer bei aktiviertem JavaScript sehen würde, müssten auch zehn verschiedene Seiten im Browser aufgerufen und interpretiert werden. Was denkst du denn, wäre die Alternative bzw wo genau siehst du einen möglichen Flaschenhals? Mit würde da nur das Rendern einfallen, wenn es ein langsamer Rechner ist. Keine Ahnung inwiefern sich der Ablauf mit "verstecktem" Fenster beschleunigen ließe. Wenn man PyQt's WebKit-Browser nutzt, geht das jedenfalls, dass man das Fenster einfach nicht anzeigt und die Anwendung nach dem Fertigladen automatisch beendet.
Verfasst: Montag 2. November 2009, 16:15
von cryzed
snafu hat geschrieben:Ja, für den Quelltext von zehn verschiedenen Seiten, so wie sie der Benutzer bei aktiviertem JavaScript sehen würde, müssten auch zehn verschiedene Seiten im Browser aufgerufen und interpretiert werden. Was denkst du denn, wäre die Alternative bzw wo genau siehst du einen möglichen Flaschenhals? Mit würde da nur das Rendern einfallen, wenn es ein langsamer Rechner ist. Keine Ahnung inwiefern sich der Ablauf mit "verstecktem" Fenster beschleunigen ließe. Wenn man PyQt's WebKit-Browser nutzt, geht das jedenfalls, dass man das Fenster einfach nicht anzeigt und die Anwendung nach dem Fertigladen automatisch beendet.
Ich meine das parsen der Seite ohne grafische Oberfläche, ohne Laden von Overhead (CSS, Grafiken, Videos) mit Python und ohne Browser Abhängigkeit - was definitiv einiges schneller ist.
Verfasst: Montag 2. November 2009, 18:12
von snafu
Wie wär's mit Flash und Grafiken im Browser deaktivieren?
Falls du das wirklich ernsthaft verfolgen willst, würde ich dir echt die WebKit-Engine ans Herz legen. Der
HTMLTokenizer könnte ein Einstieg sein. Da kommt auch einiges mit `script` im Namen vor.
Mir schwebt ja schon seit Längerem vor, mir irgendwie die Parser-Funktionalität von WebKit zunutze zu machen, eben so wie du schon sagtest. Leider bin ich noch nie wirklich durch den Code durchgestiegen als dass ich da einen Ansatz gefunden hätte auf dessen Grundlage man ein Python-Modul bauen könnte.
Verfasst: Dienstag 3. November 2009, 17:40
von cryzed
Dann hätte ich trotzdem noch den gesamten Browser als Anhängigkeit. Wenn ich Flash und Java sowie Grafiken laden deaktiviere muss ich das
für das reguläre Surfen auch wieder umstellen und es wäre dann trotzdem sicher noch lange nicht so schnell wie mit purem Python. Ganz abgesehen davon habe ich, wenn ich es mit mechanize machen würde, viel besseren Zugriff auf den Quelltext und Aktionen die ich ausführe.
Der Tokenizer schaut jetzt wie ein HTML Parser aus, oder irre ich mich?