Seite 1 von 2

Programmstatus mit Python abfragen

Verfasst: Dienstag 19. August 2008, 09:38
von bcit6k
Hallo,

ich habe ein kleines Problem. Ich öffnen einen Webbrowser und lad da eine Website. Das geht noch kein Problem. Aber ich will nun so lange warten bis die ganze Website geladen ist und erst dann mit python weitermachen.
Gibt es nun die Möglichkeit den Browserstatus ab zu rufen? das ich weis wann er fertig ist?

danke

Verfasst: Dienstag 19. August 2008, 10:19
von snafu
Geht es darum, die Seite tatsächlich im Browser zu sehen oder nur deren Inhalt weiterzuverarbeiten? Für letzteres würde sich nämlich "mechanize" anbieten, oder - sofern du einfach nur eine Seite laden willst - die urllib.

Um solche Nachfragen zu vermeiden, hätte man übrigens ein Codesnippet mitposten können, aus dem ersichtlich ist, was du bisher genau tust (inbesondere welcher Browser verwendet wird). ;)

Verfasst: Dienstag 19. August 2008, 10:34
von bcit6k
hi,

ich muss die seite schon anzeigen da ich das sonst nicht an den drucker übergeben kann. ich drucke das ganze in ein pdf.
ja klar kann ich den code posten, glaub aber in desem fall nicht das das was bringt.

als browser verwende ich ie! (zur zeit)

Code: Alles auswählen

try:
		handle = findTopWindow(wantedText="Internet Explorer")
		app = Application().connect_(handle=handle)
		print "Browserwindow found"
		err_file.writelines("Browserwindow found IE\n")
	except:
		app = Application.start("C:\Programme\Internet Explorer\IEXPLORE.EXE")
		print "Browserwindow starting"
		err_file.writelines("Browserwindow starting IE\n")
	#app.top_window_().print_control_identifiers()
	dlg = app['Internet Explorer']
	dlg = app.top_window_()
	app.dlg.control
	time.sleep(2)
	url_login= "http://localhost/login.php"
	app.top_window_().Edit.TypeKeys(url_login)
	error_msg = "type url %s \n" % url_login
	err_file.writelines(error_msg)
	app.top_window_().TypeKeys("{ENTER}")
	err_file.writelines("Enter pressed \n")
	time.sleep(3)
danke für die hilfe!

Verfasst: Dienstag 19. August 2008, 17:01
von Leonidas
Hast du mal versucht den IE via COM anzusprechen? Ich könnte mir vorstellen, dass er irgendwelche Ready-Flags hat.

Verfasst: Mittwoch 20. August 2008, 07:16
von bcit6k
hallo,

ich hab was gefunden das super funktioniert

über die win32com.client

Code: Alles auswählen

ie = Dispatch("InternetExplorer.Application")
ie.Visible = 1
ie.Navigate("www.website.de")
while ie.Busy:
	time.sleep(0.1)
danke!

Verfasst: Mittwoch 20. August 2008, 15:51
von snafu
Könnte man vielleicht auch etwas sauberer machen:

Code: Alles auswählen

while True:
    if not ie.Busy:
        break

Verfasst: Mittwoch 20. August 2008, 15:55
von Leonidas
Naja, ob eine Busy-Loop mit 100% CPU auslastung und sehr vielen Polls sinnvoll ist? Man sollte da mindestens noch ein ``time.sleep`` reinpacken.

Verfasst: Mittwoch 20. August 2008, 21:13
von snafu
Du meinst sogar eher noch die Wartezeit auf eine Sekunde erhöhen oder so?

Verfasst: Donnerstag 21. August 2008, 07:03
von Leonidas
snafu hat geschrieben:Du meinst sogar eher noch die Wartezeit auf eine Sekunde erhöhen oder so?
Nein, das vielleicht nicht, weil dann die Reaktivität sinkt. Man müsste die CPU-Auslastung im Auge behalten und einen Kompromiss zwischen Delay-Dauer und CPU-Zeit finden.

Optimal wäre es natürlich könnte man bei COM Callbacks angeben die Aufgerufen werden wenn es nicht mehr Busy ist. Da könnte man einen Ansatz wie Trellis oder Twisteds Deferreds gebrauchen.

Verfasst: Donnerstag 21. August 2008, 07:22
von BlackJack
@snafu: Ich seh nicht wo die ``while True``-Schleife sauberer ist. Nur komplizierter und damit IMHO die schlechtere Wahl.

Verfasst: Donnerstag 21. August 2008, 08:28
von snafu
Naja, kein sleep, dachte ich. Aber die Wartezeit ist ja hier sogar ausdrücklich erwünscht.

Verfasst: Donnerstag 21. August 2008, 09:10
von BlackJack
Selbst ohne `sleep()` wäre Deine Lösung komplizierter als sie sein müsste:

Code: Alles auswählen

while ie.Busy: 
    pass

Verfasst: Donnerstag 21. August 2008, 09:46
von snafu
Aha. Ich wusste nicht, dass es auch so geht.

Verfasst: Mittwoch 26. November 2008, 01:50
von DANIone
Ich krame das Thema hier noch einmal heraus, so alt ist es ja auch noch nicht...
Ich stehe nämlich vor genau demselben Problem, dass ich möchte, dass die Website, die ich per mechanize(was ja oben schon einmal erwähnt wurde) aufrufe, fertig geladen sein soll bevor das Script fortgesetzt wird.

Soweit ich herausgefunden habe gibt es allerdings nicht wie beim IE ein .Busy oder ähnliches.

Was empfehlt ihr mir, damit ich herausfinde wann die Seite fertig geladen ist und dann mein Script fortsetzen kann?

Hier mal der Code auf den es ankommt:

Code: Alles auswählen

from mechanize import Browser

br = Browser()
br.open('MeineURL')

#Hier soll nun der Check hin ob die Website fertig geladen ist

#Hier dann der nachfolgende Code

Verfasst: Mittwoch 26. November 2008, 09:32
von Leonidas
Blockiert mechanize nicht sowieso, bis es fertiggeladen hat?

Verfasst: Mittwoch 26. November 2008, 14:41
von DANIone
Du meinst also, dass es eh nicht weitergeht im script bis die seite fertig geladen ist?

Das kann natürlich sein, aber dann kann ich mir nicht erklären warum diese schleife hier:

Code: Alles auswählen

from mechanize import Browser

br = Browser()
br.open("myUrl")

a1 = "someText"
a2 = "someText"
succesfull = False
while succesfull == False:
    ready = False
    while ready == False:
        try:
            print br.geturl()
            br["feld1"] = a1
            br["feld2"] = a2
            ready = True
        except:
            ready = False
    br.submit()
    if br.geturl() == "someUrl":
        succesfull = true
Manchmal 1Mal manchmal 2Mal und manchmal öfter durchläuft, bevor es auf einmal zu einer Endlosschleife kommt, wo er immer nur
print br.geturl()
ausführt.
Er bleibt also in der ready-Schleife hängen, weil der try-Block nicht funktioniert und immer wieder der except-Block aufgerufen wird.
Die Felder("feld1" und "feld2") sind aber vorhanden, die Seite ist online, sonst würde es ja nicht manchmal 1mal 2mal etc. klappen...

Meine Theorie war jetzt also dass er irgendwann die Seite nicht schnell genug lädt, deswegen die Felder noch nicht da sind und der except-Block aufgerufen wird...

Was ich nicht verstehe ist jetzt warum er dann in der Endlosschleife hängenbleibt?
Theoretisch müsste er doch die Seite zu Ende laden und im 2. spätestens 3. Durchlauf der ready-Schleife müssten die Felder dann da sein und es müsste wieder weiter im Programm gehen?!

Ich bedanke mich schon einmal für eure Hilfe:)

Verfasst: Mittwoch 26. November 2008, 14:48
von Leonidas
Die konkrete Ausnahme siehst du da ja nicht, weil du sie mit einem ``except`` verschluckt. Soetwas sollte man eigentlich nie machen, weil sie eben alle Fehler, auch solche die du nicht erwartest und die unter Umständen anders behandelt werden sollten bzw. das Programm überhaupt erst dubugbar machen unterdrückst. Lass das ganze ``try`` einfach mal weg. Überhaupt sieht das alles sehr kompliziert aus, was soll das Programm denn eigentlich machen? Formulare mit den gleichen Daten ausfüllen bis irgendwann eine bestimmte URL erreicht wird?

Verfasst: Mittwoch 26. November 2008, 15:04
von DANIone
Ok also der Error der dann produziert wird ist ein "ControlNotFoundError", wobei die Control ja vorhanden ist, denn durch

Code: Alles auswählen

print br.geturl()
erkenne ich ja, dass der Browser auf derselben Seite ist.
Es muss also denke ich so sein, wie ich angenommen habe, dass die Seite noch nicht fertig geladen ist.

Nein ich fülle die Felder nicht immer mit dem demselben Text aus, sondern habe eine Variable dafür, die ich variiere.
Dies tut er dann solange bis er auf eine bestimmte Seite kommt und Ende...

Was kann ich also tun damit die Seite erst fertig lädt und dann die Control gesucht wird?

Hier nochmal mein jetziger Code:

Code: Alles auswählen

from mechanize import Browser

br = Browser()
br.open('myUrl')

a1 = "someText"
a2 = "someText"
succesfull = False
while succesfull == False:
    print br.geturl()
    #Hier soll jetzt gewartet werden bis die Seite fertig geladen wurde,
    #damit kein ControlNotFoundError kommt
    br.select_form(nr=0)
    br["feld1"] = a1
    br["feld2"] = a2
    br.submit()
    if br.geturl() == "someUrl":
        succesfull = true
Danke für die Hilfe:)

Verfasst: Donnerstag 27. November 2008, 09:46
von da.dom
HuHu...

interessantes Thema mit COM. Hat da jemand eine etwas ausfürliche Einführung parat? Hab bisher immer nur kurze Abrisse über das Thema gefunden.

Grüße
D

Verfasst: Donnerstag 27. November 2008, 11:37
von BlackJack
@DANIone: Bist Du sicher dass das Control *wirklich* da ist? Ich könnte mir durchaus vorstellen, dass die Website mitbekommt, dass jemand in viel zu kurzen Abständen die Seite mit verschiedenen Werten für das selbe Eingabefeld aufruft, und entsprechend eine Seite ausliefert, die zum Beispiel dazu auffordert die Bruteforce-Password-Crack-Versuche bitte zu unterlassen. :twisted: