2009-09-09 14 views
7

Estoy tratando de descargar el archivo con Python usando IE:La descarga de archivos utilizando IE del pitón

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, me estoy poniendo una ventana que pide al usuario que desea guardar el archivo. ¿Cómo puedo guardar este archivo automáticamente desde Python?

necesito utilizar algún navegador, no urllib o mecanizar, porque antes de la descarga de archivos que necesito para interactuar con algunas funciones ajax.

+0

Creo que es un comportamiento definido por el usuario en las preferencias. – rogeriopvl

+0

He examinado las API desde http://msdn.microsoft.com/en-us/library/aa752084%28VS.85%29.aspx# y http://msdn.microsoft.com/en-us/library /aa752085%28VS.85%29.aspx# y no creo que sea posible guardar el archivo. –

Respuesta

8

Esto funciona para mí, siempre y cuando los diálogos de IE están en el primer plano y el archivo descargado no existe 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"); 
+1

Esto funciona genial, gracias! – infrared

1

No necesita utilizar IE. Se podría utilizar 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.

actualizarse una vez más: Al hacer clic en el botón que se genera mediante JavaScript, si la URL es recuperado no calculada por el código JavaScript, y sólo el botón es así, entonces tal vez usted puede 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.

+0

Dijo "Necesito usar algún navegador, no urllib o mecanizar, porque antes de descargar el archivo necesito pasar muchas cosas de ajax". –

+0

Eso no estaba en la pregunta original. –

+0

Antes de comenzar a descargar, necesito iniciar sesión en el sitio web. A continuación, haga clic en algunos enlaces que iniciarán algunos scripts de Java. Los scripts escriben el contenido del sitio web (sin recarga). Este nuevo botón crear en el sitio web que hacen posibilidad de descargar mi archivo ... Así que no creo que pueda utilizar urlib2 ... – Adam

1

Si no puede controlar Internet Explorer utilizando su interfaz COM, sugiero usar el AutoIt COM para controlar su GUI desde Python.

+0

Autolt se ve bien. Pero quiero escribir una pequeña aplicación que solo obtenga este archivo y use datos de él. Prefiero una pequeña solución inteligente ... – Adam

4

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

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

Para un proyecto, que tenía que escribir un programa Python que simularía un navegador y acceder a cualquiera de redes sociales diferentes (recordar Friendster? Orkut? CyberWorld? Yo), y subir imágenes y texto en el cuenta del usuario, incluso captando CAPTCHAs e interacciones complejas de JavaScript. Pure Python lo hace (comparativamente) fácil; como ya has visto, tratar de usar IE lo hace imposible.

+0

parece que nunca ha experimentado solicitudes de ajax de ingeniería inversa para una aplicación de tercera parte llena de artilugios 'ajax' dotnet extraños - infierno puro. –

+3

@Paulo - ¿Has leído mi respuesta?Sí, he escrito 20 o 30 raspadores, lo que implica quizás 100 solicitudes AJAX o de página que tuvieron que ser de ingeniería inversa, una gran parte de mi trabajo durante más de un año. No son fáciles, como dije, ¿pero comparados con tratar de hacerlo a través de un maldito objeto COM? Eso es como tratar de elegir un candado en comparación con intentar agarrar un candado * usando mitones para el horno *. – Malvolio

+0

[HttpFox] (https://addons.mozilla.org/en-US/firefox/addon/6647/) es bueno para la ingeniería inversa este tipo de cosas. – Brian

0

Tengo algo así (una horrible aplicación de 3ra parte con muchos controles dotnet 'ajax' raros), y uso el plugin de iMacros para que Firefox haga 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 de VNC. Mire algo como http://code.google.com/p/python-vnc-viewer/ para inspirarse.

+0

Gracias, lo voy a ver. – Adam

1

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

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

Y WebKit debe ser lo suficientemente potente 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_()) 
3

pamie quizá

P.A.M.I.E. - significa Python Módulo automatizado para I.E.

uso principal

de Pamie es para comprobar web sitios por los que automatizan el cliente de Internet Explorer utilizando el lenguaje Pamie secuencias de comandos. PAMIE es ¡no es un motor de reproducción de discos!

Pamie le permite automatizar I.E. por manipulación del documento de I.E. Objeto Modelo a través de COM. Esta herramienta gratuita es para utilizada por Quality Assurance Engineers y Desarrolladores.

0

Este es, sin duda absolutamente el último camino Normalmente haría esto, pero hoy tuve que recurrir a golpes para conseguir algo que funcionara. Tengo IE 10 así que la respuesta de @cgohlke no funcionará (sin texto de ventana). Todos los intentos de obtener una versión adecuada de Autenticación de cliente funcionaban correctamente, así que tuvimos que recurrir a esto. Tal vez ayude a alguien más que está igualmente al límite de sus fuerzas.

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!

Cuestiones relacionadas