繁体   English   中英

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

[英]python's webbrowser launches IE, instead of default browser, on Windows relative path

我试图在默认浏览器中从 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://的 url 然后做一个os.path.exists检查和os.path.realpath可能是答案。

我的主要问题是通过尝试将file://到相对路径而导致 URL 错误。 它可以通过以下方式修复:

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

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

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

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

  1. GenericBrowser由环境变量BROWSER设置,并且是第一个。
  2. WindowsDefault是第二个。
  3. 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 或修改我的路径都会让我获得正确的浏览器,并显示更好的错误消息。

感谢您的帮助,如果没有您的想法,我无法解决此问题。

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

您需要注册 Chrome webbrowser ,因为它似乎不是预定义的浏览器类型之一,然后您应该能够做到这一点:

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 的预定义默认值。

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

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

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

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

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

它将在 Chrome 中打开一个新标签,而

webbrowser.open("example.com")

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

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

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

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

在 Python 3.6、Windows 10 上对我有用的是使用register()函数和BackgroundBrowser来登录我想要的浏览器:

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类。

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

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

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

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

我在 Firefox 上也有同样的问题。 http://www.google.com在 ff 中打开,而 file:///test.html 在 IE 中打开。

网络浏览器文档说:

请注意,在某些平台上,尝试使用此函数打开文件名可能会起作用并启动操作系统的关联程序。 但是,这既不支持也不可移植。

这个问题只出现在file:///协议 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)

用这个:

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

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

命令需要在列表中,而不是在单个字符串中! (在这种情况下,“开始”,“文件路径”),shell 也需要为 True(Windows)

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

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

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

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

你可以这样修复:

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM