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.register
和BROWSER
环境变量,那么这将是一个很好的信息。文档没有详细说明。
看起来'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 并看到错误消息而不是浏览器来验证这一点。
GenericBrowser
和 BackgroundBrowser
都将调用 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 中对我有用的是使用带有 BackgroundBrowser
的 register()
函数来登录我想要的浏览器:
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() 不起作用
Py thon2的webbrowser如何在python3用