Javascript ausführen

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Benutzeravatar
cryzed
User
Beiträge: 82
Registriert: Samstag 28. März 2009, 15:53

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.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

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
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
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.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

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)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

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.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

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
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

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. :roll: Es kränkt mich sogar etwas.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
cryzed
User
Beiträge: 82
Registriert: Samstag 28. März 2009, 15:53

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!
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

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?
the more they change the more they stay the same
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

gerold hat geschrieben:Mich deshalb über JavaScript aufzuklären halte ich für etwas übertrieben. :roll: Es kränkt mich sogar etwas.
Oh, tut mir leid. Das hab ich nicht beabsichtigt. :oops:

Ich wusste nur nicht, wie viel du mit XUL/JavaScript außerhalb des Browsers schon gemacht hast, daher hab ich einfach mal mehr geschrieben.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
cryzed
User
Beiträge: 82
Registriert: Samstag 28. März 2009, 15:53

Dav1d hat geschrieben: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?
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.
Benutzeravatar
snafu
User
Beiträge: 6868
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
Benutzeravatar
cryzed
User
Beiträge: 82
Registriert: Samstag 28. März 2009, 15:53

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!
nemomuk
User
Beiträge: 862
Registriert: Dienstag 6. November 2007, 21:49

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.
Benutzeravatar
cryzed
User
Beiträge: 82
Registriert: Samstag 28. März 2009, 15:53

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?
Benutzeravatar
snafu
User
Beiträge: 6868
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
Benutzeravatar
cryzed
User
Beiträge: 82
Registriert: Samstag 28. März 2009, 15:53

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.
Benutzeravatar
snafu
User
Beiträge: 6868
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
Benutzeravatar
cryzed
User
Beiträge: 82
Registriert: Samstag 28. März 2009, 15:53

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?
Antworten