2009-09-09 158 views
7

下載使用IE文件我嘗試使用IE下載文件與Python:從蟒蛇

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

在此之後,我得到一個窗口,詢問用戶在哪裏保存文件。我怎樣才能從python自動保存這個文件?

我需要使用某些瀏覽器,不是的urllib或機械化,因爲下載文件之前,我需要一些Ajax功能互動。

+0

我認爲這是用戶在首選項中定義的行爲。 – rogeriopvl 2009-09-09 10:21:27

+0

我已經查看了http://msdn.microsoft.com/en-us/library/aa752084%28VS.85%29.aspx#和http://msdn.microsoft.com/en-us/library中的API /aa752085%28VS.85%29.aspx#,我不認爲可以保存該文件。 – 2009-09-09 18:05:01

回答

8

這隻要在IE對話框是在前景和下載的文件不已經在「另存爲」目錄中爲我的作品:

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

這很好,謝謝! – infrared 2011-01-04 12:03:07

1

您不需要使用IE。您可以使用類似

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

更新:我看你已經更新了你的問題。如果你需要使用瀏覽器,那麼顯然這個答案不適合你。

進一步更新:當您單擊由JavaScript生成的,如果檢索到的網址是由JavaScript計算,只有按鈕是按鈕,然後你可以或許通過urllib2檢索URL。另一方面,您可能還需要從已驗證的會話中傳遞會話Cookie。

+0

他/她說:「我需要使用一些瀏覽器,而不是urllib或機械化,因爲在下載文件之前,我需要通過許多Ajax的東西。」 – 2009-09-09 10:25:17

+0

這不是原來的問題。 – 2009-09-09 10:29:48

+0

在我開始下載之前,我需要登錄網站。然後點擊一些將啓動一些Java腳本的鏈接。腳本正在寫入網站的內容(無需重新加載)。這個網站上,這使得可能創造新的按鈕下載我的文件... 所以我不認爲我可以使用urlib2 ... – Adam 2009-09-09 10:31:35

1

如果使用它的COM接口Internet Explorer,可以不用管,我建議使用AutoIt COM控制在Python的GUI。

+0

Autolt看起來不錯。但我想寫一個小應用程序,它只是獲取這個文件並使用它的數據。我更喜歡一些小巧的智能解決方案...... – Adam 2009-09-09 10:44:18

4

我不知道如何很好地這樣說,但是這聽起來像是約在最近的記憶中最魯莽的軟件的想法。 Python比IE更有能力執行AJAX調用。

要訪問數據,是的,你可以使用urlliburllib2。如果響應中有JSON數據,則存在json庫;同樣對於XML和HTML,還有BeautifulSoup

對於一個項目,我必須編寫一個Python程序來模擬瀏覽器並登錄到不同的社交網絡(記住Friendster?Orkut?Cyber​​World?我會這樣做),並將圖像和文本上傳到用戶的帳戶,甚至可以掌握CAPTCHA和複雜的JavaScript交互。純Python使它(相對)更容易;正如你已經看到的,試圖使用IE使它不可能。

+0

看起來像你從來沒有經歷過逆向工程ajax請求的一些第三方應用程序充滿奇怪的dotnet'ajax'部件 - 純粹地獄。 – 2010-12-30 20:42:53

+3

@Paulo - 你看過我的回答嗎?是的,我寫了20或30個垃圾郵件,需要100個AJAX或頁面請求,這些垃圾郵件必須進行反向設計 - 這是我工作超過一年的很大一部分。正如我所說,它們並不容易,但與通過一個怪異的COM對象試圖做到這一點相比呢?這就像試圖挑選鎖相比試圖選擇一個鎖*戴烤箱手套*。 – Malvolio 2010-12-30 21:25:56

+0

[HttpFox](https://addons.mozilla.org/en-US/firefox/addon/6647/)可以很好地對這種事情進行反向工程。 – Brian 2011-01-03 18:33:51

0

我有類似的東西(有很多怪異的dotnet的「AJAX」控制一個可怕的第三部分應用程序),我用的iMacros插件的Firefox做一些自動化。但我正在做批量插入,而不是下載。

您可以嘗試錄製,編輯和重放通過VNC會話發送的輸入。看看像http://code.google.com/p/python-vnc-viewer/這樣的靈感。

+0

謝謝,我會看看它。 – Adam 2010-12-31 02:06:09

1

一個選項也可以嵌入您自己的瀏覽器。

這就是說,例如,可能通過Qt通過PyQt(GPL)或PySide(LGPL)。在那裏你可以嵌入WebKit引擎。然後,您可以在QWebView中顯示該頁面,並讓用戶導航至您的下載並過濾該事件,或者使用簡單的QWebPage,其中所有內容都可以自動完成並且根本不需要顯示任何內容。

WebKit應該足以做任何你想做的事情。

非常簡單的例子:

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也許

P.A.M.I.E. - 代表Python的自動化模塊 I.E.

Pamie的主要用途是用於測試的網站,通過它使用 Pamie腳本語言自動化 Internet Explorer客戶端 網站。 PAMIE是 不是唱片播放引擎!

Pamie允許您自動化I.E.通過 通過COM操縱I.E.的文檔對象 模型。此免費工具用於 質量保證工程師 和開發人員使用。

0

這絕對絕對是最後的辦法我通常會這樣做,但今天我確實不得不求助於做一些工作。我有IE 10所以@ cgohlke的答案將無法正常工作(無窗口文本)。所有嘗試獲得正確版本的客戶端身份驗證的工作都失敗了,因此不得不採取這種措施。也許它會幫助那些同樣處於末尾的人。

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) 

但是男人,這太可怕了!