Python - 从 Internet 下载 .exe 文件

Posted

技术标签:

【中文标题】Python - 从 Internet 下载 .exe 文件【英文标题】:Python - Downloading a .exe file from the internet 【发布时间】:2011-04-26 22:44:23 【问题描述】:

在为我的程序创建自动更新程序的过程中,我无法成功下载 .exe 文件。

我正在做的事情是这样的:

import urllib

url = '--insert-url--'

f = urllib.urlopen(url)
file = f.read()
f.close
f2 = open('download.exe', 'w')
f2.write(file)
f2.close

我在下载时没有遇到任何错误,但是当我尝试运行执行时,我收到以下错误:

这个文件的版本不是 与Windows版本兼容 你在跑。检查你的电脑 系统信息看你是否 需要 x86(32 位)或 x64(64 位) 程序的版本,然后 联系软件发行商。

我自己上传了执行,之前运行良好。

我还尝试了一些我发现的其他各种下载方法,这导致了同样的错误,我还尝试上传到不同的网站以确保不是这样。

我需要用什么特殊的方法来做这件事吗?

编辑:

我对下载做了一些进一步的测试。我在另一台计算机(32 位系统)上运行程序(我正在使用 Spencer 现在发布的内容)。 (我的是 64 位的。)我在那台计算机上没有收到错误,但是当我运行程序时,会出现命令行,因为它是我用作我的命令行样式的 .exe测试下载,但是在我必须结束程序之前,闪烁的白色输入栏的东西只是在整个地方反弹,所以显然有些东西已经损坏了。

另外,下载过程是否可以使用批处理文件?这几乎会更容易,因为无论如何程序都必须重新启动才能开始使用新的更新,因为它使用的是全新的 .exe。 (我将使用 py2exe 将程序制作为 .exe。)

【问题讨论】:

由于文件扩展名是“.exe”,我假设您在 Windows 上执行此操作。尝试将f2 文件的模式更改为'wb',以二进制模式写入。默认为文本模式,同时会将遇到的所有换行符(字节)更改为回车+换行符。 如果你手动下载(通过网络浏览器访问)并执行它,你会遇到同样的问题吗? @Senthil 如果我手动下载它可以正常工作。 【参考方案1】:

根据 urllib 的官方 python 文档:

一个警告:read() 方法,如果 size 参数被省略或为负, 直到数据结束才能读取 溪流;没有好办法 确定整个流从 一个套接字已被读取一般 案例。

来自同一个库的替代方案是

import urllib

url = '--insert-url--' 

filename = 'download.exe'  
urllib.urlretrieve(url, filename)

【讨论】:

……非常有趣,我没有意识到这一点。如果这是解决方案,请在此处发表评论,以便我注意到。 好像加快了下载速度,但还是不行。【参考方案2】:

我怀疑您需要在对open 的调用中包含b(二进制)标志:

导入 urllib url = '--插入-url--' f = urllib.urlopen(url) 文件 = f.read() f.close() f2 = open('download.exe', 'wb') f2.write(文件) f2.close()

此外,您在致电.close() 时忽略了父母。不确定这是否是您的理解或示例的问题,但我已经在上面的代码中修复了它。

另外,如果您的.exe 很大,您可能希望在下载文件时将其写入文件(目前您正在将整个内容读入内存)。这看起来像:

f2 = open("download.exe", "wb")
try:
    while True:
        data = f.read(4096)
        if not data:
            break
        f2.write(data)
finally:
    f.close()
    f2.close()

【讨论】:

这很奇怪。您能否将使用 Python 下载的.exe 与“工作”.exe 进行比较以查看差异? (我不使用 Windows,所以我不能推荐 diff 工具……但我相信 Google 会有一些建议) 我用过WinDiff,发现的唯一区别是它们的创建日期不同。 你必须小心差异程序,如果他们不做二进制差异,那么他们可能会给你一个假阴性。 确实,windiff 不支持二进制比较。 有人知道支持二进制文件的免费差异程序吗?【参考方案3】:

所以,我想你可能遇到了不同的问题。

我的规格:Python3.X,通过 Homebrew 安装。使用 Python 的 urllib.request 模块,因为它是当前支持的模块。

我认为您正在下载一个 html 页面,该页面将您重新路由到下载链接。如果您尝试从链接下载,情况尤其如此。许多网站和服务器都让您单击一个按钮,该按钮将提供不同的 url 供您下载。

例如,如果您尝试下载任何Microsoft link,例如 FCIV 校验和程序,下载按钮实际上会引导您通过不同的 url。


回答

我的建议是将原始答案中下载的字节文件加载为 .htm/l 文件。从这里,您可以尝试查找带有应用程序扩展的 url;

例如,如果您坚持使用 FCIV 示例,您将下载会出现相同错误的内容:

此文件的版本与您运行的 Windows 版本不兼容。检查您计算机的系统信息,看看您是否需要 x86(32 位)或 x64(64 位)版本的程序,然后联系软件发行商。

仔细检查后,如果您将此文件加载为 .htm/l 文件,您可以搜索 x86 字符串并发现它位于实际名称为 https://download.microsoft.com/download/c/f/4/cf454ae0-a4bb-4123-8333-a1b6737712f7/Windows-KB841290-x86-ENU.exe 的 url 上,然后,如果您尝试下载在带有这个新 url/https 请求的 OP 中,您实际上将拥有一个正确的 .exe。


编辑对不起,这个答案可能只适用于 2017 年的 Python3.X。答案比 6 年前提出的原始问题有点晚。此外,关于文件写入中b 标志的其他答案和cmets 是正确的。该文件应以wb 权限打开。

【讨论】:

以上是关于Python - 从 Internet 下载 .exe 文件的主要内容,如果未能解决你的问题,请参考以下文章

QNetworkAccessManager 从 Internet 崩溃中下载图像预览

通过中断的连接从 Internet 下载文件

saveFileDialog 停止工作 + 从 Internet 下载文件

java #Image从Internet.java下载

Java - 如果 src 有连字符,则无法从 Internet 下载图像

避免“从 Internet 下载的应用程序”警告