【问题标题】:How to open external programs in Python如何在 Python 中打开外部程序
【发布时间】:2016-09-11 08:11:37
【问题描述】:

重复编辑:不,我这样做了,但它不想启动 Firefox。 我正在做一个 cortana/siri 助手的东西,我想让它在我说什么的时候打开一个网络浏览器。所以我已经完成了 if 部分,但我只需要它来启动 firefox.exe 我尝试了不同的东西,但我得到了一个错误。这是代码。请帮忙!它适用于打开记事本,但不适用于 firefox..

#subprocess.Popen(['C:\Program Files\Mozilla Firefox\firefox.exe']) opens the app and continues the script
#subprocess.call(['C:\Program Files\Mozilla Firefox\firefox.exe']) this opens it but doesnt continue the script

import os
import subprocess

print "Hello, I am Danbot.. If you are new ask for help!" #intro

prompt = ">"     #sets the bit that indicates to input to >

input = raw_input (prompt)      #sets whatever you say to the input so bot can proces

raw_input (prompt)     #makes an input


if input == "help": #if the input is that
 print "*****************************************************************" #says that
 print "I am only being created.. more feautrues coming soon!" #says that
 print "*****************************************************************" #says that
 print "What is your name talks about names" #says that
 print "Open (name of program) opens an application" #says that
 print "sometimes a command is ignored.. restart me then!"
 print "Also, once you type in a command, press enter a couple of times.."
 print "*****************************************************************" #says that

raw_input (prompt)     #makes an input

if input == "open notepad": #if the input is that
 print "opening notepad!!" #says that
 print os.system('notepad.exe') #starts notepad

if input == "open the internet": #if the input is that
 print "opening firefox!!" #says that
 subprocess.Popen(['C:\Program Files\Mozilla Firefox\firefox.exe'])

【问题讨论】:

  • 使用firefox.exe的绝对路径。
  • 记事本通常在 PATH 变量下的 system32 文件夹中,但 firefox 不太可能。
  • user3549596 什么意思?这是路径:C:\Program Files\Mozilla Firefox\firefox.exe
  • ...至少显示实际错误!只是默默地无法打开浏览器窗口吗?它是否抛出异常?哪个例外?等等。如果您的错误与输入处理没有任何关系,则根本不需要显示有关输入处理的代码;把那些零件拿出来。

标签: python bots launch


【解决方案1】:

简短的回答是os.system 不知道在哪里可以找到firefox.exe

一个可能的解决方案是使用完整路径。并且推荐使用subprocess模块:

import subprocess

subprocess.call(['C:\Program Files\Mozilla Firefox\\firefox.exe'])

firefox.exe 之前注意\\!如果您使用\f,Python 会将其解释为换页:

>>> print('C:\Program Files\Mozilla Firefox\firefox.exe')
C:\Program Files\Mozilla Firefox
                                irefox.exe

当然,这条路不存在。 :-)

所以要么转义反斜杠,要么使用原始字符串:

>>> print('C:\Program Files\Mozilla Firefox\\firefox.exe')
C:\Program Files\Mozilla Firefox\firefox.exe
>>> print(r'C:\Program Files\Mozilla Firefox\firefox.exe')
C:\Program Files\Mozilla Firefox\firefox.exe

请注意,使用os.systemsubprocess.call 将停止当前应用程序,直到启动的程序完成。所以你可能想改用subprocess.Popen。这将启动外部程序,然后继续执行脚本。

subprocess.Popen(['C:\Program Files\Mozilla Firefox\\firefox.exe', '-new-tab'])

这将打开 Firefox(或在正在运行的实例中创建一个新选项卡)。


一个更完整的例子是我通过 github 发布的 open 实用程序。这使用正则表达式将文件扩展名与打开这些文件的程序相匹配。然后它使用subprocess.Popen 在适当的程序中打开这些文件。作为参考,我在下面添加了当前版本的完整代码。

请注意,这个程序是为类 UNIX 操作系统编写的。在 ms-windows 上,您可能会从注册表中获取文件类型的应用程序。

"""Opens the file(s) given on the command line in the appropriate program.
Some of the programs are X11 programs."""

from os.path import isdir, isfile
from re import search, IGNORECASE
from subprocess import Popen, check_output, CalledProcessError
from sys import argv
import argparse
import logging

__version__ = '1.3.0'

# You should adjust the programs called to suit your preferences.
filetypes = {
    '\.(pdf|epub)$': ['mupdf'],
    '\.html$': ['chrome', '--incognito'],
    '\.xcf$': ['gimp'],
    '\.e?ps$': ['gv'],
    '\.(jpe?g|png|gif|tiff?|p[abgp]m|svg)$': ['gpicview'],
    '\.(pax|cpio|zip|jar|ar|xar|rpm|7z)$': ['tar', 'tf'],
    '\.(tar\.|t)(z|gz|bz2?|xz)$': ['tar', 'tf'],
    '\.(mp4|mkv|avi|flv|mpg|movi?|m4v|webm)$': ['mpv']
}
othertypes = {'dir': ['rox'], 'txt': ['gvim', '--nofork']}


def main(argv):
    """Entry point for this script.

    Arguments:
        argv: command line arguments; list of strings.
    """
    if argv[0].endswith(('open', 'open.py')):
        del argv[0]
    opts = argparse.ArgumentParser(prog='open', description=__doc__)
    opts.add_argument('-v', '--version', action='version',
                      version=__version__)
    opts.add_argument('-a', '--application', help='application to use')
    opts.add_argument('--log', default='warning',
                      choices=['debug', 'info', 'warning', 'error'],
                      help="logging level (defaults to 'warning')")
    opts.add_argument("files", metavar='file', nargs='*',
                      help="one or more files to process")
    args = opts.parse_args(argv)
    logging.basicConfig(level=getattr(logging, args.log.upper(), None),
                        format='%(levelname)s: %(message)s')
    logging.info('command line arguments = {}'.format(argv))
    logging.info('parsed arguments = {}'.format(args))
    fail = "opening '{}' failed: {}"
    for nm in args.files:
        logging.info("Trying '{}'".format(nm))
        if not args.application:
            if isdir(nm):
                cmds = othertypes['dir'] + [nm]
            elif isfile(nm):
                cmds = matchfile(filetypes, othertypes, nm)
            else:
                cmds = None
        else:
            cmds = [args.application, nm]
        if not cmds:
            logging.warning("do not know how to open '{}'".format(nm))
            continue
        try:
            Popen(cmds)
        except OSError as e:
            logging.error(fail.format(nm, e))
    else:  # No files named
        if args.application:
            try:
                Popen([args.application])
            except OSError as e:
                logging.error(fail.format(args.application, e))


def matchfile(fdict, odict, fname):
    """For the given filename, returns the matching program. It uses the `file`
    utility commonly available on UNIX.

    Arguments:
        fdict: Handlers for files. A dictionary of regex:(commands)
            representing the file type and the action that is to be taken for
            opening one.
        odict: Handlers for other types. A dictionary of str:(arguments).
        fname: A string containing the name of the file to be opened.

    Returns: A list of commands for subprocess.Popen.
    """
    for k, v in fdict.items():
        if search(k, fname, IGNORECASE) is not None:
            return v + [fname]
    try:
        if b'text' in check_output(['file', fname]):
            return odict['txt'] + [fname]
    except CalledProcessError:
        logging.warning("the command 'file {}' failed.".format(fname))
        return None


if __name__ == '__main__':
    main(argv)

【讨论】:

  • (我还复制了我的 firefox 位置的确切路径)好的,所以我确实做了 subprocces 代码,当我尝试从中启动 firefox 时,它说:Traceback(最近一次调用最后一次) :文件“Danbot.py”,第 33 行,在 subprocess.Popen(['C:\Program Files\Mozilla Firefox\firefox.exe']) 文件“c:\hp\bin\python\lib\subprocess .py”,第 593 行,在 init 错误读取,错误写入)文件“c:\hp\bin\python\lib\subprocess.py”,第 793 行,在 _execute_child 启动信息中)WindowsError:[错误 22 ] 文件名、目录名或卷标语法不正确
  • @Dan 猜测,这可能是因为 Python 将 '\f' 解释为换页符的转义序列。将\f 更改为\\f
  • 什么 \f ?我没有对 \f.. 使用任何东西?
  • 是的。当 Python 读取 'C:\Program Files\Mozilla Firefox\firefox.exe' 时,它会解释 \f 并将其替换为换页符。所以你得到C:\Program Files\Mozilla Firefox<formfeed>irefox.exe',这当然不存在。 :-)
  • 你需要双斜杠 `\` 在所有这些上,而不仅仅是最后一个...
【解决方案2】:

如果您想在网络上打开 Google 或其他内容,只需 import webbrowser 并打开 URL。我会给你一个简单的例子。

import webbrowser

webbrowser.open("www.google.com")

【讨论】:

  • 问题不在于在网络上打开某些东西(Firefox 只是一个例子),也不在于具有某些外部程序功能的 Python 包。这是关于对外部程序的调用,并且已经有一个通用的答案。所以这根本不是答案。
猜你喜欢
  • 1970-01-01
  • 2013-02-09
  • 2015-10-01
  • 1970-01-01
  • 2021-04-25
  • 1970-01-01
  • 1970-01-01
  • 2017-09-27
  • 1970-01-01
相关资源
最近更新 更多