【问题标题】:python's webbrowser launches IE, instead of default browser, on Windows relative pathpython 的 webbrowser 在 Windows 相对路径上启动 IE,而不是默认浏览器
【发布时间】: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?

标签: python windows browser default python-webbrowser


【解决方案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 没有给出问题的指示,所有其他浏览器都有一个很好的消息说他们找不到文件。

            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 或修改我的路径都会为我提供正确的浏览器和更好的错误消息。

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

            【讨论】:

            • 我不需要附加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 变量添加到您的系统变量并放置默认浏览器的路径。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-04-16
                    • 1970-01-01
                    • 2022-06-29
                    相关资源
                    最近更新 更多