Estoy tratando de descargar un 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, recibo una ventana preguntando 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 .

8
Adam 9 sep. 2009 a las 14:18

8 respuestas

La mejor respuesta

Esto funciona para mí siempre que los cuadros de diálogo 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");
10
cgohlke 4 ene. 2011 a las 22:25

Esta es definitivamente la última forma en que normalmente haría esto, pero hoy tuve que recurrir a golpear para que algo funcionara. Tengo IE 10, así que la respuesta de @ cgohlke no funcionará (sin texto de ventana). Todos los intentos de conseguir que funcionara una versión adecuada de la Autenticación del cliente estaban fallando, así que tuve que recurrir a esto. Tal vez ayude a alguien más que está igualmente al final de su relación.

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)

Pero hombre, ¿es horrible!

0
Jamie Bull 21 jun. 2013 a las 19:46

Tengo algo así (una aplicación de tercera parte horrible con muchos controles extraños 'ajax' de dotnet), 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. Mire algo como http://code.google.com/p/python-vnc- espectador / para inspirarte.

0
Paulo Scardine 30 dic. 2010 a las 20:37

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

Eso es p. posible con Qt a través de PyQt (GPL) o PySide (LGPL). Allí podría incrustar el motor WebKit. Luego, puede mostrar la página en un QWebView y dejar que el usuario navegue a su descargue y filtre ese evento o use un simple QWebPage donde todo podría automatizarse y nada tiene que mostrarse en absoluto.

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

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_())
1
Chris 31 dic. 2010 a las 16:56

No necesita usar 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 apropiada para usted.

Actualización adicional: cuando hace clic en el botón generado por JavaScript, si la URL recuperada es no calculada por JavaScript, y solo el botón lo es, 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 desde su sesión autenticada.

1
Vinay Sajip 9 sep. 2009 a las 10:45

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

1
Cristian Ciupitu 9 sep. 2009 a las 10:27

pamie quizás

P.A.M.I.E. - significa Python Automated Module para I.E.

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

Pamie te permite automatizar I.E. manipulando el modelo de objeto de documento de I.E.con COM. Esta herramienta gratuita es para uso de ingenieros y desarrolladores de control de calidad.

3
John La Rooy 1 ene. 2011 a las 11:54

No sé cómo decir esto amablemente, pero esto suena como la idea de software más imprudente de la memoria reciente. Python es mucho más capaz de realizar llamadas AJAX que IE.

Para acceder a los datos, sí, puede usar 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 programa Python que simulara un navegador e iniciar sesión en cualquiera de las 20 redes sociales diferentes (¿recuerdas Friendster? ¿Orkut? ¿CyberWorld? Sí) y subir imágenes y texto a la cuenta del usuario, incluso captando CAPTCHA e interacciones complejas de JavaScript. Pure Python lo hace (comparativamente) fácil; como ya has visto, intentar usar IE lo hace imposible.

4
Malvolio 30 dic. 2010 a las 19:15