Descarga de archivos usando IE desde python

Estoy intentando descargar el archivo con Python usando IE:

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') 

Después de esto, aparece una ventana que le pregunta al usuario dónde guardar el archivo. ¿Cómo puedo guardar este archivo automáticamente desde python?

Necesito usar algún navegador , no urllib o mecanizar, porque antes de descargar el archivo necesito interactuar con alguna funcionalidad ajax .

Esto me funciona siempre que los diálogos de IE estén en primer plano y el archivo descargado no exista en el directorio “Guardar como”:

 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"); 

No sé cómo decirlo bien, pero esto parece ser la idea de software más temeraria de la memoria reciente. Python es mucho más capaz de realizar llamadas AJAX que IE.

Para acceder a los datos, sí, puede utilizar urllib y urllib2 . Si hay datos JSON en la respuesta, está la biblioteca json ; Del mismo modo para XML y HTML, hay BeautifulSoup .

Para un proyecto, tuve que escribir un progtwig de Python que simulara un navegador e iniciar sesión en cualquiera de las 20 redes sociales diferentes (¿recuerdas Friendster? ¿Orkut? ¿CyberWorld? Sí) y subí imágenes y texto a la cuenta del usuario, incluso captando CAPTCHAs y complejas interacciones de JavaScript. Pure Python lo hace (comparativamente) fácil; Como ya has visto, tratar de usar IE lo hace imposible.

pamie quizás

PAMIE – significa Python Automated Module For IE

El uso principal de Pamie es para probar sitios web mediante los cuales usted automatiza el cliente de Internet Explorer usando el lenguaje de scripting Pamie. PAMIE no es un motor de reproducción de grabación!

Pamie le permite automatizar IE manipulando el modelo de objetos de documentos de IE a través de COM. Esta herramienta gratuita es para uso de los ingenieros y desarrolladores de control de calidad.

Si no puede controlar Internet Explorer utilizando su interfaz COM, le sugiero que use AutoIt COM para controlar su GUI desde Python.

No es necesario utilizar IE. Podrías usar algo como

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

Actualización: veo que has actualizado tu pregunta. Si necesita usar un navegador, entonces claramente esta respuesta no es adecuada para usted.

Actualización adicional: cuando hace clic en el botón generado por JavaScript, si la URL recuperada no es calculada por JavaScript, y solo el botón es, entonces tal vez pueda recuperar esa URL a través de urllib2 . Por otro lado, es posible que también deba pasar una cookie de sesión de su sesión autenticada.

Una opción también podría ser incrustar su propio navegador.

Eso es posible, por ejemplo, con Qt a través de PyQt (GPL) o PySide (LGPL). Allí podríamos incrustar el motor de WebKit. Luego, puede mostrar la página en un QWebView y dejar que el usuario navegue a su descarga y filtrar ese evento o usar una QWebPage simple donde todo podría automatizarse y no se debe mostrar nada.

Y WebKit debería ser lo suficientemente poderoso como para hacer lo que quieras.

Ejemplo muy básico:

 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_()) 

Tengo algo así (una aplicación tremenda de la tercera parte con muchos controles ‘ajax’ de dotnet extraños), y uso el complemento iMacros para Firefox para hacer algo de automatización. Pero estoy haciendo inserciones por lotes, no descargas.

Puede intentar grabar, editar y reproducir las entradas enviadas a través de una sesión VNC. Mira algo como http://code.google.com/p/python-vnc-viewer/ en busca de inspiración.

Esta es definitivamente la última forma en la que normalmente haría esto, pero hoy tuve que recurrir a los golpes para que algo funcionara. Tengo IE 10, por lo que la respuesta de @cgohlke no funcionará (sin texto de ventana). Todos los bashs de obtener una versión correcta de la Autenticación del Cliente funcionaron mal, por lo que tuvimos que recurrir a esto. Tal vez ayude a otra persona que esté igualmente al final de su atadura.

 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'', 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)</download> 

Pero hombre, ¡es horrible!