【问题标题】:Downloading file using IE from python使用 IE 从 python 下载文件
【发布时间】:2010-11-26 19:03:06
【问题描述】:

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

【问题讨论】:

标签: python internet-explorer com


【解决方案1】:

只要 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");

【讨论】:

    【解决方案2】:

    我不知道如何说得好,但这听起来像是最近记忆中最鲁莽的软件创意。与 IE 相比,Python 执行 AJAX 调用的能力要强得多。

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

    对于一个项目,我必须编写一个 Python 程序来模拟浏览器并登录到任何 20 个不同的社交网络(记得 Friendster?Orkut?Cyber​​World?我知道),然后上传图片和文本到用户的帐户,甚至掌握验证码和复杂的 JavaScript 交互。纯 Python 使它(相对)容易;正如您已经看到的,尝试使用 IE 是不可能的。

    【讨论】:

    • 似乎您从未经历过逆向工程 ajax 请求,因为您需要对一些充满奇怪 dotnet 'ajax' 小部件的第 3 部分应用程序进行逆向工程 ajax 请求 - 纯属地狱。
    • @Paulo -- 你读过我的回答吗?是的,我已经写了 20 或 30 个爬虫,可能需要 100 个 AJAX 或页面请求,这些请求必须进行逆向工程——这是我一年多工作的重要组成部分。正如我所说,它们并不容易,但与尝试通过一个该死的 COM 对象来实现它相比?这就像试图撬锁相比试图撬锁戴着烤箱手套
    • HttpFox 非常适合逆向工程这种事情。
    • 谢谢。我使用 Firebug,其中的 Net 选项似乎与 HttpFox 相当,但对每个人来说都是他自己的。
    • 嗨。如果可以的话,是的,可以使用 Python 自己的网络例程。但考虑一下我的情况——我们使用一个经过 NTLM 身份验证的代理。出于某种原因,我根本无法让 requests_ntlm 与 py2exe 一起使用。我必须想出别的办法,现在试图找到解决方法。这个咆哮只是说,有边缘情况...... :)
    【解决方案3】:

    pamie 或许

    P.A.M.I.E. - 代表 Python 用于 I.E. 的自动化模块

    Pamie 的主要用途是测试网络 自动化的站点 Internet Explorer 客户端使用 帕米脚本语言。帕米是 不是唱片播放引擎!

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • Autolt 看起来不错。但我想编写一个小应用程序,它只获取这个文件并使用其中的数据。我更喜欢一些小的智能解决方案......
      【解决方案5】:

      您不需要使用 IE。你可以使用类似的东西

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

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

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

      【讨论】:

      • 他/她说“我需要使用一些浏览器,而不是 urllib 或 mechanize,因为在下载文件之前我需要传递许多 ajax 东西。”
      • 原始问题中没有。
      • 在开始下载之前,我需要先登录网站。然后单击一些链接,这些链接将启动一些 java 脚本。脚本正在编写网站的内容(无需重新加载)。这在网站上创建了新按钮,可以下载我的文件......所以我认为我不能使用 urlib2......
      • 不幸的是“按钮”是:Export Selected
      • @Adam:您可以使用 urllib,但这意味着检查和反向工程 javascript 和 ajax 调用。除了痛苦之外,它还很脆弱:如果网站更改了您的应用程序就会中断。考虑要求网站所有者提供一些更适合自动化的替代接口(如 Web 服务),如果不可能,祝你好运!
      【解决方案6】:

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

      例如可以通过PyQt (GPL) 或 PySide (LGPL) 使用 Qt。在那里你可以嵌入 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_())
      

      【讨论】:

        【解决方案7】:

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

        您可以尝试记录、编辑和回放通过 VNC 会话发送的输入。查看 http://code.google.com/p/python-vnc-viewer/ 之类的内容以获取灵感。

        【讨论】:

          【解决方案8】:

          这绝对是我通常会这样做的最后一种方式,但今天我确实不得不求助于敲打才能让某些东西发挥作用。我有 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)
          

          但是,伙计,这很可怕吗!

          【讨论】:

            猜你喜欢
            • 2014-09-27
            • 1970-01-01
            • 1970-01-01
            • 2017-06-01
            • 2020-02-06
            • 1970-01-01
            • 2020-05-25
            • 2012-11-12
            • 2017-01-23
            相关资源
            最近更新 更多