python 的 webbrowser 在 Windows 相对路径上启动 IE,而不是默认浏览器

Posted

技术标签:

【中文标题】python 的 webbrowser 在 Windows 相对路径上启动 IE,而不是默认浏览器【英文标题】:python's webbrowser launches IE, instead of default browser, on Windows relative path 【发布时间】:2011-08-20 10:49:45 【问题描述】:

我正在尝试在默认浏览器中从 python 启动一个本地 html 文件(现在我的默认设置是 Google Chrome,如果我双击一个 .html 文件,Chrome 就会启动。)

当我使用 python 的webbrowser.open() 时,IE 会启动,但地址栏为空白。

Python 2.7.1 (r271:86832, Nov 27 2010, 17:19:03) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import webbrowser
>>> filename = 'test.html'
>>> webbrowser.open('file://'+filename)
True
>>> print(webbrowser.get().__class__.__name__)
WindowsDefault

我检查了我的默认程序,它们看起来是正确的。我在 Win 7 SP1 上。为什么 Chrome 没有启动?

更新:代码将在未知的操作系统和机器上运行,因此硬编码或注册浏览器或路径更新不是选项。我在想,解析file:// 的网址,然后进行os.path.exists 检查和os.path.realpath 可能是答案。

【问题讨论】:

Shadikka 查看源代码,我引用了文档,Acorn 在代码中给出了实用的建议。总之,它们是一个非常完整的答案。 虽然如果有人知道如何使用webbrowser.registerBROWSER 环境变量,那么这将是一个很好的信息。文档没有详细说明。 看起来'file://' 与相对路径的结合导致了问题。如果我放弃'file://' 或使用os.path.realpath(filename) 它可以工作,谷歌就会启动。我仍然想知道为什么一个错误的文件 url 会回退到带有空白地址栏的 IE。 McLeopold:因为 Windows 会根据每个扩展决定打开哪个浏览器(我忘记了它对目录的默认行为,更不用说空路径或无效路径了)。您可以将 Chrome 作为 Windows 默认浏览器,但仍将 IE 作为与 .MP3、.GIF 扩展等相关联的应用程序(或者实际上是 RealPlayer 或任何其他二进制文件)。请在您的问题中编辑这些详细信息。您是否只想保证 Windows 会针对特定类型的扩展程序打开 Chrome? 【参考方案1】:

您可以使用get(name) 来使用特定的浏览器。

You'll need to register the Chrome webbrowser,因为它似乎不是predefined browser types 之一,然后你应该可以这样做:

webbrowser.get('chrome').open('http://www.google.com')

更新:

实际上,您可能只能执行以下操作之一:

webbrowser.get('windows-default').open('http://www.google.com') webbrowser.get('macosx').open('http://www.google.com')

文档没有显示 Linux 的预定义默认值。

【讨论】:

【参考方案2】:

查看module source code,它首先尝试使用Windows 默认浏览器,但如果不起作用,它会搜索作为命令的常用浏览器名称,即。在 PATH 变量中。尝试将 Web 浏览器的位置添加到 PATH。

【讨论】:

【参考方案3】:

webbrowser 模块应该使用默认浏览器,所以这可能是一个错误。另一方面,使用docs 中的解释来解决您的问题:

如果环境变量BROWSER 存在,它被解释为覆盖 浏览器的平台默认列表, 作为 os.pathsep 分隔的列表 浏览器按顺序尝试。当。。。的时候 列表部分的值包含 字符串 %s,则将其解释为 文字浏览器命令行是 与替换的参数 URL 一起使用 对于 %s;如果该部分不包含 %s,它被简单地解释为 要启动的浏览器的名称。

【讨论】:

【参考方案4】:

我在使用 Firefox 时遇到了同样的问题。 http://www.google.com 在 ff 中打开,而 file:///test.html 在 IE 中打开。

webbrowser doc 说:

请注意,在某些平台上,尝试 使用此功能打开文件名, 可以工作并开始运行 系统的相关程序。然而, 这既不支持也不 便携。

【讨论】:

【参考方案5】:

这个问题只出现在file:/// 协议 URL 上,这些 URL 可能没有注册到 chrome,所以 os.startfile()(这是 webbrowser.open 在 Windows 上尝试的第一件事)在 Internet Explorer 中打开它们。我认为将您的其他浏览器放在 PATH 中不会有帮助,因为 os.startfile() 在尝试路径中的浏览器之前仍然会被调用。

可以做的是检查注册表中http:// 的默认浏览器(例如,通过检查注册表项HKEY_CLASSES_ROOT\http\shell\open\command)并将该浏览器用于file:/// URL .不漂亮,但应该可以。

import _winreg
import webbrowser
import shlex
import subprocess

def win_browser_open(url):
    if url.startswith('file:///'):
        browser = _winreg.QueryValue(_winreg.HKEY_CLASSES_ROOT, r'http\shell\open\command')
        browser = browser.replace('%1', url)
        subprocess.Popen(shlex.split(browser))
    else:
        webbrowser.open(url)

【讨论】:

【参考方案6】:

我的主要问题是通过尝试将 file:// 添加到相对路径而导致 URL 错误。可以这样解决:

webbrowser.open('file://' + os.path.realpath(filename))

使用webbrowser.open 将尝试多种方法,直到一个“成功”,这是一个松散的定义。

WindowsDefault 类调用 os.startfile() 失败并返回 False。我可以通过在 windows 运行命令中输入 URL 并看到错误消息而不是浏览器来验证这一点。

GenericBrowserBackgroundBrowser 都将调用 subprocess.Popen() 并使用一个成功的 exe,即使 URL 错误也是如此,并返回 True。 IE 没有给出问题的指示,所有其他浏览器都有一个很好的消息说他们找不到文件。

    GenericBrowser 由环境变量BROWSER 设置,是第一个。 WindowsDefault 排在第二位。 BackgroundBrowser 是最后一个,如果没有其他方法,则包括后备 IE。

这是我原来的设置:

>>> import webbrowser
>>> webbrowser._tryorder
['windows-default',
 'C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE']
>>> webbrowser._browsers.items()
[('windows-default', [<class 'webbrowser.WindowsDefault'>, None]),
 ('c:\\program files\\internet explorer\\iexplore.exe', [None, <webbrowser.BackgroundBrowser object at 0x00000000022E3898>])]
>>>

这是我修改环境变量后的设置:

C:>path=C:\Program Files (x86)\Mozilla Firefox;%path%

C:>set BROWSER=C:\Users\Scott\AppData\Local\Google\Chrome\Application\chrome.exe

C:>python
Python 2.7.1 (r271:86832, Nov 27 2010, 17:19:03) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import webbrowser
>>> webbrowser._tryorder
['C:\\Users\\Scott\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe',
 'windows-default',
 'firefox',
 'C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE']
>>> webbrowser._browsers.items()
[('windows-default', [<class 'webbrowser.WindowsDefault'>, None]),
 ('c:\\program files\\internet explorer\\iexplore.exe',[None, <webbrowser.BackgroundBrowser object at 0x000000000235E828>]),
 ('firefox', [None, <webbrowser.BackgroundBrowser object at 0x000000000235E780>]),
 ('c:\\users\\scott\\appdata\\local\\google\\chrome\\application\\chrome.exe', [None, <webbrowser.GenericBrowser object at 0x000000000235E8D0>])]
>>>

webbrowser._tryorder 给出了尝试过的浏览器列表。注册 chrome 或添加 BROWSER env var 或修改我的路径都会为我提供正确的浏览器和更好的错误消息。

感谢大家的帮助,如果没有你们的想法,我无法解决这个问题。

【讨论】:

我不需要附加file://use os.path.realpath(),我什至在我的路径中添加了..!一旦我得到正确的文件路径,它就会在我的默认浏览器(chrome)中打开,但是当我的路径错误时(在我的情况下忘记了..),它默认为 IE。如果有/\ 的部分路径甚至都没有关系! 您甚至不必将 chrome 设置为您的浏览器。只要它是默认浏览器并且您的路径包含在 os.path.realpath(path) 中,您就会在 chrome 中成功启动【参考方案7】:

这为我打开了一个新的 Chrome 标签页,它仍然独立于操作系统:

webbrowser.get().open('http://www.google.com')

奇怪的是,没有get() 调用,它仍然使用IE。这看起来像一个简单的解决方法的错误。

【讨论】:

您正在打开一个 http 资源。问题是关于打开文件资源,我认为区别很重要 谢谢您,先生!这实际上是迄今为止唯一可行的解​​决方案!正如 McLeopold 指出的那样,其他浏览器可能存在实际错误?.. @PeterGraham 答案适用于任何协议,包括file://【参考方案8】:

简而言之,使用 Windows 10,不包含 https://example.com 格式的完整 URL 的所有内容都会在 IE 中为我打开。例如,如果我说

webbrowser.open("https://www.example.com")

它会在 Chrome 中打开一个新标签页,同时

webbrowser.open("example.com")

将打开 IE。任何.get() 都会导致它根本无法打开浏览器。

有点奇怪的行为,但我可以看到这是一个复杂的实现,并且很可能操作系统应该为这种行为负责。

【讨论】:

我认为这不是操作系统的错。我在 macOS 中遇到了同样的问题。不使用完整的 URL 会导致网站在 Firefox 中打开,而我的默认浏览器是 Safari。【参考方案9】:

在 Python 3.6、Windows 10 中对我有用的是使用带有 BackgroundBrowserregister() 函数来登录我想要的浏览器:

import webbrowser

# Register your preferable browser
browser_path = 'C:/path/to/opera.exe'
webbrowser.register('opera', None, webbrowser.BackgroundBrowser(browser_path))

# Get an instance and launch your file
browser = webbrowser.get('opera') 
browser.open('html_file')

额外观察 -

webbrowser 还有一个GenericBrowser 类。

查看source,似乎BackgroundBrowser 在调用subprocess.Popen() 时使用start_new_session,而GenericBrowser 没有。

我不知道该标志的确切功能。

然而,实际上,使用BackgroundBrowser 会切换到浏览器窗口,而GenericBrowser 只是打开选项卡,但不会切换。

【讨论】:

【参考方案10】:

使用这个:

import webbrowser
webbrowser.get('windows-default').open('http://www.google.com')

【讨论】:

【参考方案11】:

由于所有答案都没有解决这个/我的问题,这种方式对我有用...(windows)

命令需要在列表中,而不是在单个字符串中! (在这种情况下,“start”、“filepath”),shell 也需要为 True(windows)

import subprocess
subprocess.Popen(['start', 'C:/Users/User/Desktop/convert_report.html'], shell=True)

【讨论】:

对不起,没有。这不是一个适当的解决方案。您只使用subprocess.Popen(..., shell=True) 来获得与其他方式相同的系统路径解析功能。您应该直接执行webbrowser 文档告诉您的操作,就像其他答案告诉您的那样。更糟糕的是,不必要地使用subprocess.Popen() can open you up to command injection attacks。由于许多不同的原因,这个答案很糟糕。 这是第四个原因:仅仅因为(Windows)用户有一个 PATH 环境变量,并不意味着它是非空的并且保证包含到 Chrome 或其他任何东西的有效路径。 (这在新的/未配置的机器或虚拟机上很常见)。【参考方案12】:

webbrowser 模块似乎在 cwd 中找不到文件名,因为您是通过快捷方式或终端打开程序,所以 cwd 与程序的目录不同。

在这种情况下,在给webbrowser.open函数提供路径时,必须将路径转换为程序目录的绝对路径。

程序的路径存储为__file__全局常量。

你可以这样修复:

webbrowser.open(os.path.join(__file__, '..', filename))

我通过这个解决方案解决了同样的问题。

【讨论】:

【参考方案13】:

将 BROWSER 变量添加到您的系统变量并放置默认浏览器的路径。

【讨论】:

以上是关于python 的 webbrowser 在 Windows 相对路径上启动 IE,而不是默认浏览器的主要内容,如果未能解决你的问题,请参考以下文章

Python:chrome.exe 的通用 webbrowser.get().open() 不起作用

[Winform]js与webbrowser交互

Py thon2的webbrowser如何在python3用

关于python的webbrowser

在WebBrowser控件中使用时,document.hidden错误地为false

如何在 Lynx 等 webbrowser 或 python webbrowser 上添加 xmpp 或矩阵协议?