2009-09-09 13 views
7

Sto cercando di scaricare il file con Python utilizzando IE:download di file utilizzando IE in pitone

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

Dopo questo, sto diventando una finestra che chiede all'utente dove salvare il file. Come posso salvare questo file automaticamente da Python?

ho bisogno di utilizzare alcuni del browser, non urllib o meccanizzare, perché prima che il download del file ho bisogno di interagire con alcune funzionalità Ajax.

+0

Credo che sia un comportamento definito dall'utente nelle preferenze. – rogeriopvl

+0

Ho esaminato le API da http://msdn.microsoft.com/en-us/library/aa752084%28VS.85%29.aspx# e http://msdn.microsoft.com/en-us/library /aa752085%28VS.85%29.aspx# e non penso sia possibile salvare il file. –

risposta

8

Questo funziona per me fino a quando le finestre di dialogo di IE sono in primo piano e il file scaricato non esiste già nella directory "Salva con nome":

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

Funziona alla grande, grazie! – infrared

1

Non è necessario utilizzare IE. Si potrebbe usare qualcosa come

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

Aggiornamento: Vedo che hai aggiornato la tua domanda. Se hai bisogno di usare un browser, allora chiaramente questa risposta non è appropriata per te.

Ulteriore aggiornamento: Quando si fa clic sul pulsante che è generato da JavaScript, se l'URL recuperato è non calcolato dal JavaScript, e solo il pulsante è, allora si può forse recuperare l'URL via urllib2. D'altra parte, potrebbe anche essere necessario passare un cookie di sessione dalla sessione autenticata.

+0

Ha detto "Devo usare un browser, non urllib o mechanize, perché prima di scaricare il file ho bisogno di passare molte cose ajax". –

+0

Non era nella domanda originale. –

+0

Prima di iniziare a scaricare, devo accedere al sito web. Quindi fare clic su alcuni collegamenti che avvieranno alcuni script java. Gli script stanno scrivendo i contenuti del sito web (senza ricaricare). Questo creare nuovo pulsante sul sito web che rendono possibilità di scaricare il mio file ... Quindi non credo che posso usare urlib2 ... – Adam

1

Se non riesci a controllare Internet Explorer utilizzando la sua interfaccia COM, ti suggerisco di utilizzare la COM AutoIt per controllare la sua GUI da Python.

+0

Sembra buono. Ma voglio scrivere una piccola applicazione che ottiene questo file e usa i dati da esso. Io preferisco una piccola soluzione intelligente ... – Adam

4

Non so come dirlo bene, ma questo suona come l'idea del software più sconsiderata nella memoria recente. Python è molto più capace di effettuare chiamate AJAX rispetto a IE.

Per accedere ai dati, sì, è possibile utilizzare urllib e urllib2. Se nella risposta sono presenti dati JSON, c'è la libreria json; allo stesso modo per XML e HTML, c'è BeautifulSoup.

Per un progetto, ho dovuto scrivere un programma Python che simulare un browser e accedere a qualsiasi diversi social network (ricordate Friendster? Orkut? CyberWorld? Faccio io), e caricare immagini e testo nel account utente, comprendendo anche CAPTCHA e interazioni JavaScript complesse. Pure Python lo rende (relativamente) facile; come hai già visto, provare a utilizzare IE lo rende impossibile.

+0

sembra che tu non abbia mai sperimentato richieste di ajax di reverse engineering per alcune applicazioni di terze parti piene di bizzarri widget "ajax", un vero inferno. –

+3

@Paulo - hai letto la mia risposta?Sì, ho scritto 20 o 30 scrapers, con forse 100 AJAX o richieste di pagine che dovevano essere decodificate - una grande parte del mio lavoro per più di un anno. Non sono facili, come ho detto, ma rispetto a provare a farlo attraverso un oggetto COM bizzarro? È come cercare di scegliere un lucchetto rispetto al tentativo di scegliere un lucchetto * con guanti da forno *. – Malvolio

+0

[HttpFox] (https://addons.mozilla.org/en-US/firefox/addon/6647/) è ottimo per il reverse engineering di questo tipo di cose. – Brian

0

Ho qualcosa del genere (una tremenda applicazione di 3a parte con molti controlli ajax "weird dotnet"), e io uso il plugin iMacros per Firefox per fare un po 'di automazione. Ma sto facendo inserimenti in batch, non download.

È possibile provare a registrare, modificare e riprodurre gli input inviati tramite una sessione VNC. Guarda qualcosa come http://code.google.com/p/python-vnc-viewer/ per l'ispirazione.

+0

Grazie, lo guarderò. – Adam

1

Un'opzione potrebbe anche essere quella di incorporare il proprio browser.

Thats ad es. possibile con Qt tramite PyQt (GPL) o PySide (LGPL). Lì potresti incorporare il motore WebKit. È quindi possibile visualizzare la pagina in un QWebView e consentire all'utente di passare al download e filtrare tale evento o utilizzare un semplice QWebPage in cui tutto potrebbe essere automatizzato e nulla deve essere mostrato affatto.

E WebKit dovrebbe essere abbastanza potente da fare tutto ciò che vuoi.

esempio molto semplice:

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 forse

P.A.M.I.E. - sta per Python Modulo automatizzato per I.E.

uso principale

di Pamie serve a verificare web siti con cui automatizzare Internet Explorer cliente utilizzando il linguaggio di Pamie scripting. PAMIE è non un motore di riproduzione dei record!

Pamie consente di automatizzare I.E. di manipolando l'oggetto documento di I.E. Modello tramite COM. Questo strumento gratuito è per uso da Quality Assurance Engineers e sviluppatori.

0

questo è sicuramente assolutamente l'ultimo modo Normalmente lo farei ma oggi ho dovuto ricorrere a sbattere per ottenere qualcosa lavorando. Ho IE 10 così la risposta @ cgohlke non funzionerà (nessun testo finestra). Tutti i tentativi di ottenere una versione corretta dell'autenticazione client funzionante stavano fallendo, quindi è stato necessario ricorrere a questo. Forse aiuterà qualcun altro che è ugualmente alla fine del loro potere.

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) 

Ma amico, è orribile!

Problemi correlati