使用来自python的IE下载文件

时间:2009-09-09 10:18:42

标签: python internet-explorer com

我正在尝试使用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功能进行交互

8 个答案:

答案 0 :(得分: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 :(得分:4)

我不知道怎么说这个很好,但这听起来像是近期记忆中最愚蠢的软件理念。 Python比IE更能执行AJAX调用。

要访问数据,是的,您可以使用urlliburllib2。如果响应中有JSON数据,则存在json库;同样对于XML和HTML,有BeautifulSoup

对于一个项目,我必须编写一个Python程序来模拟浏览器并登录任何 20 不同的社交网络(记得Friendster?Orkut?Cyber​​World?我这样做),并上传图片并将文本写入用户的帐户,甚至可以掌握CAPTCHA和复杂的JavaScript交互。纯Python使它(相对)容易;正如您已经看到的那样,尝试使用IE使其无法实现。

答案 2 :(得分:3)

pamie或许

  

P.A.M.I.E。 - 代表Python   I.E。

的自动化模块      

Pamie的主要用途是测试网络   您自动化的网站   使用Internet Explorer客户端   Pamie脚本语言。 PAMIE是   不是记录播放引擎!

     

Pamie允许您自动化I.E.通过   操纵I.E.的文档对象   通过COM建模。这个免费工具适用于   由质量保证工程师使用   和开发人员。

答案 3 :(得分:1)

您不需要使用IE。你可以使用像

这样的东西
import urllib2
data = urllib2.urlopen("http://website/file.xml").read()

更新:我看到您更新了问题。如果您需要使用浏览器,那么这个答案显然不适合您。

进一步更新:当您点击由JavaScript生成的按钮时,如果检索到的网址是而不是由JavaScript计算,只有按钮是,那么您也许可以通过urllib2检索该网址。另一方面,您可能还需要从经过身份验证的会话中传递会话cookie。

答案 4 :(得分:1)

如果您无法使用其COM接口控制Internet Explorer,我建议使用AutoIt COM从Python控制其GUI。

答案 5 :(得分:1)

一个选项也可以是嵌入您自己的浏览器。

多数,例如可以通过PyQt(GPL)或PySide(LGPL)使用Qt。在那里你可以嵌入WebKit引擎。然后,您可以在QWebView中显示该页面,让用户导航到您的下载并过滤该事件,或者使用简单的QWebPage,其中所有内容都可以自动完成,并且根本不需要显示任何内容。< / p>

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

答案 6 :(得分:0)

我有类似的东西(一个非常糟糕的第三部分应用程序,有许多奇怪的dotnet'ajax'控件),我使用iMacros插件为Firefox做一些自动化。但我正在进行批量插入,而不是下载。

您可以尝试记录,编辑和重播通过VNC会话发送的输入。看看像http://code.google.com/p/python-vnc-viewer/这样的灵感。

答案 7 :(得分: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)

但男人,这太可怕了!