2009-09-09 6 views
7

Ich versuche Datei mit Python mit IE zum Download:IE Download-Datei aus Python mit

from win32com.client import DispatchWithEvents 

class EventHandler(object): 
    def OnDownloadBegin(self): 
     pass 

ie = DispatchWithEvents("InternetExplorer.Application", EventHandler) 

ie.Visible = 0 

ie.Navigate('http://website/file.xml') 

Danach ist ich den Benutzer zu fragen, wo ein Fenster immer die Datei zu speichern. Wie kann ich diese Datei automatisch von Python speichern?

Ich muss einige Browser verwenden, nicht urllib oder mechanisieren, weil vor Datei herunterzuladen ich mit einigen Ajax-Funktionalität interagieren müssen.

+0

Ich glaube, das ist ein Verhalten, das vom Benutzer in den Einstellungen definiert ist. – rogeriopvl

+0

Ich habe die APIs von http://msdn.microsoft.com/en-us/library/aa752084%28VS.85%29.aspx# und http://msdn.microsoft.com/en-us/library angeschaut /aa752085%28VS.85%29.aspx# und ich denke nicht, dass es möglich ist, die Datei zu speichern. –

Antwort

8

Das ist für mich funktioniert, solange die IE-Dialoge im Vordergrund stehen und die heruntergeladene Datei nicht existiert bereits im „Speichern unter“ Verzeichnis:

import time 
import threading 
import win32ui, win32gui, win32com, pythoncom, win32con 
from win32com.client import Dispatch 

class IeThread(threading.Thread): 
    def run(self): 
     pythoncom.CoInitialize() 
     ie = Dispatch("InternetExplorer.Application") 
     ie.Visible = 0 
     ie.Navigate('http://website/file.xml') 

def PushButton(handle, label): 
    if win32gui.GetWindowText(handle) == label: 
     win32gui.SendMessage(handle, win32con.BM_CLICK, None, None) 
     return True 

IeThread().start() 
time.sleep(3) # wait until IE is started 
wnd = win32ui.GetForegroundWindow() 
if wnd.GetWindowText() == "File Download - Security Warning": 
    win32gui.EnumChildWindows(wnd.GetSafeHwnd(), PushButton, "&Save"); 
    time.sleep(1) 
    wnd = win32ui.GetForegroundWindow() 
if wnd.GetWindowText() == "Save As": 
    win32gui.EnumChildWindows(wnd.GetSafeHwnd(), PushButton, "&Save"); 
+1

Das funktioniert super, danke! – infrared

1

Sie müssen IE nicht verwenden. Man könnte so etwas wie

import urllib2 
data = urllib2.urlopen("http://website/file.xml").read() 

Update verwenden: Ich sehe Sie Ihre Frage aktualisiert haben. Wenn Sie einen Browser verwenden müssen, ist diese Antwort eindeutig nicht für Sie geeignet.

Weitere Update: Wenn Sie auf die Schaltfläche klicken, die von JavaScript generiert wird, wenn die abgerufene URL nicht vom JavaScript berechnet ist, und nur die Taste ist, dann kann man vielleicht die URL über urllib2 abzurufen. Auf der anderen Seite müssen Sie möglicherweise auch ein Sitzungscookie aus Ihrer authentifizierten Sitzung übergeben.

+0

Er/sie sagte: "Ich brauche einen Browser, nicht urllib oder mechanisieren, weil vor dem Herunterladen der Datei ich viele Ajax-Zeug übergeben muss." –

+0

Das war nicht in der ursprünglichen Frage. –

+0

Bevor ich mit dem Download beginnen kann, muss ich mich auf der Webseite einloggen. Klicken Sie dann auf einige Links, die einige Java-Skripte starten. Skripte schreiben Inhalte der Website (ohne Nachladen). Dieses schaffen neue Schaltfläche auf der Webseite der Möglichkeit Gebrauch machen, meine Datei herunterzuladen ... Also ich glaube nicht, dass ich urlib2 verwenden kann ... – Adam

1

Wenn Sie Internet Explorer über seine COM-Schnittstelle nicht steuern können, empfehle ich die Verwendung der COM, um die GUI von Python zu steuern.

+0

Autolt gut aussehen. Aber ich möchte kleine Anwendung schreiben, die nur diese Datei erhalten und Daten daraus verwenden. Ich bevorzuge einige kleine intelligente Lösung ... – Adam

4

Ich weiß nicht, wie ich das schön sagen soll, aber das klingt nach der tollkühnsten Software-Idee in letzter Zeit. Python ist viel besser in der Lage, AJAX-Aufrufe durchzuführen als IE.

Um auf die Daten zugreifen zu können, können Sie urllib und urllib2 verwenden. Wenn in der Antwort JSON-Daten vorhanden sind, gibt es die Bibliothek json; Auch für XML und HTML gibt es BeautifulSoup.

Für ein Projekt, hatte ich ein Python-Programm zu schreiben, das einen Browser simulieren würde und melden Sie sich in einem der verschiedenen sozialen Netzwerken (nicht vergessen, Friendster? Orkut? Cyberworld? Ich), und Bilder und Texte in das Hochladen Benutzerkonto, sogar CAPTCHAs und komplexe JavaScript-Interaktionen. Pure Python macht es (vergleichsweise) einfach; Wie Sie bereits gesehen haben, macht es den Versuch unmöglich, IE zu verwenden.

+0

scheint, wie Sie nie Reverse-Engineering-Ajax-Anfragen für einige dritte Teil Anwendung voller seltsamen dotnet 'Ajax' Widgets - pure Hölle erlebt. –

+3

@Paulo - hast du meine Antwort gelesen?Ja, ich habe 20 oder 30 Scraper geschrieben, was vielleicht 100 AJAX- oder Page-Requests beinhaltet, die reverse-engineered sein mussten - ein großer Teil meiner Arbeit seit mehr als einem Jahr. Sie sind nicht einfach, wie ich sagte, aber verglichen mit dem Versuch, es durch ein verdammtes COM-Objekt zu tun? Das ist, als würde man versuchen, ein Schloss zu knacken, als wenn man versucht, ein Schloss * mit Ofenhandschuhen * zu greifen. – Malvolio

+0

[HttpFox] (https://addons.mozilla.org/en-US/firefox/addon/6647/) ist gut für das Reverse-Engineering dieser Art von Sache. – Brian

0

Ich habe so etwas (eine schreckliche Anwendung des 3. Teils mit vielen seltsamen dotnet 'ajax' Kontrollen), und ich benutze das iMacros Plugin für Firefox, um etwas Automatisierung zu machen. Aber ich mache Batch-Einsätze, keine Downloads.

Sie können versuchen, die über eine VNC-Sitzung gesendeten Eingaben aufzuzeichnen, zu bearbeiten und wiederzugeben. Betrachten Sie etwas wie http://code.google.com/p/python-vnc-viewer/ zur Inspiration.

+0

Danke, ich werde es betrachten. – Adam

1

Eine Möglichkeit könnte auch sein, einen eigenen Browser einzubetten.

Das ist z.B. möglich mit Qt über PyQt (GPL) oder PySide (LGPL). Dort könnte man die WebKit-Engine einbetten. Sie können dann entweder die Seite in einem QWebView anzeigen lassen und den Benutzer zu Ihrem Download navigieren lassen und dieses Ereignis filtern oder eine einfache QWebPage verwenden, wo alles automatisiert werden kann und nichts angezeigt werden muss.

Und WebKit sollte mächtig genug sein, um alles zu tun, was Sie wollen.

Sehr einfaches Beispiel:

import sys 

from PySide import QtCore, QtGui, QtWebKit 

url = 'http://developer.qt.nokia.com/wiki/PySideDownloads/' 

class TestKit(QtCore.QObject): 
    def __init__(self, app): 
     self.page = QtWebKit.QWebPage() 
     self.page.loadFinished.connect(self.finished) 
     self.page.mainFrame().load(QtCore.QUrl(url)) 
     self.app = app 

    def finished(self, evt): 
     # inspect DOM -> navigate to next page or download 
     print self.page.currentFrame().documentElement().toInnerXml().encode(
       'utf-8') 
     # when everything is done 
     self.app.quit() 


if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    t = TestKit(app) 
    sys.exit(app.exec_()) 
3

pamie vielleicht

P.A.M.I.E. - steht für Python Automatisiertes Modul für I.E.

Pamie Haupt Verwendung ist für Testen von Web- Websites, mit denen Sie den Internet Explorer Client mit der Pamie Skriptsprache automatisieren. PAMIE ist keine Aufnahme-Engine!

Mit Pamie können Sie I.E. von Manipulieren I.E.'s Document Object Modell über COM. Dieses kostenlose Tool ist für Verwendung von Quality Assurance Engineers und Entwickler.

0

Dies ist auf jeden Fall absolut letzte Weg Normalerweise würde ich das tun, aber heute musste ich darauf zurückgreifen, dass etwas funktioniert. Ich habe IE 10 also @ cgohlkes Antwort wird nicht funktionieren (kein Fenstertext). Alle Versuche, eine korrekte Version der Client-Authentifizierung zu erhalten, scheiterten, so dass wir darauf zurückgreifen mussten. Vielleicht hilft es einem anderen, der am Ende seiner Kräfte ist.

import IEC 
import pywinauto 
import win32.com 

# Creates a new IE Window 
ie = IEC.IEController(window_num=0) 

# Register application as an app for pywinauto 
shell = win32com.client.Dispatch("WScript.Shell") 
pwa_app = pywinauto.application.Application() 
w_handle = pywinauto.findwindows.find_windows(title=u'<Title of the site - find it using SWAPY>', class_name='IEFrame')[0] 
window = pwa_app.window_(handle=w_handle) 
window.SetFocus() 

# Click on the download link 
ie.ClickLink(<download link>) 

# Get the handle of the Open Save Cancel dialog 
ctrl = window['2'] 

# You may need to adjust the coords here to make sure you hit the button you want 
ctrl.ClickInput(button='left', coords=(495, 55), double=False, wheel_dist=0) 

Aber Mann, ist es schrecklich!