簡體   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