Hi,

I can use webbrowser.open_new(url) to open an browser window easily, but how do I close this browser window ?

I have searched the web and still not able to find a solution. Another way of doing this might be to start the browser window in a separate program (progA) then use another program to kill the program (progA) but this is very crude, and how do I do this ? I am very new to python.

Thanks

Here is a rather crude method, using subprocess

import subprocess as sp
import time
def browse(url, how_long):
    child = sp.Popen("firefox %s" % url, shell=True)
    time.sleep(how_long)
    child.terminate()
browse("http://www.python.org", 3)

However, on my system, this closes firefox only if it's not already running when the call to Popen happens.
If you only need to display an html page and then close the window, you could also use wxpython instead of your web browser, see this code snippet.

Gribouillis, thank you for your reply. However, I got the error code as below :

Traceback (most recent call last):
File "popen.py", line 7, in <module>
browse("http://www.python.org", 3)
File "popen.py", line 6, in browse
child.terminate()
AttributeError: 'Popen' object has no attribute 'terminate'

The a new tab has successfully open but still not able to close.

Thanks

Popen.terminate() is new in python 2.6, as well as Popen.kill() .

Dear Gribouillis,

Thank you for your prompt reply. I have install python2.6.2 and the error disappear. However, the child.terminate() still does not work.

I have actually closed all firefox windows and use the python program to start the browser, the browser window just stay open after the program completed with no error.

I managed to close the window on linux by creating a second instance of firefox. To do this I create a new profile for filefox (which I called "foo"). You can do this with the command firefox -profilemanager . Then I start firefox with

child = sp.Popen('firefox -p foo -no-remote %s' % url, shell=True)

The window closes on child.terminate()

Dear Gribouillis,

I have followed your instruction and has created a separate firefox profile, but the window stay even after the program completed (I have tried start with no other firefox and with a default firefox open, but both tries share the same result). Anyway, following are the output of the program and see if there is anything I did wrongly.

I have also do a ps -ef and see that the new profile (and also the default profile) firefox ppid is 1, is this OK ?

kk@blissful:~/Download$ python26 popen.py
kk@blissful:~/Download$ ps -ef | grep firefox
kk 11904 1 10 12:08 ? 00:02:11 /usr/lib/firefox-3.0.13/firefox
kk 12392 1 8 12:29 pts/0 00:00:01 /usr/lib/firefox-3.0.13/firefox -p music -no-remote http://www.python.org
kk 12406 11101 0 12:29 pts/0 00:00:00 grep firefox
kk@blissful:~/Download$

kk@blissful:~/Download$ python26 -v popen.py
# installing zipimport hook
import zipimport # builtin
# installed zipimport hook
# /home/kk/Python/python26/lib/python2.6/site.pyc matches /home/kk/Python/python26/lib/python2.6/site.py
import site # precompiled from /home/kk/Python/python26/lib/python2.6/site.pyc
# /home/kk/Python/python26/lib/python2.6/os.pyc matches /home/kk/Python/python26/lib/python2.6/os.py
import os # precompiled from /home/kk/Python/python26/lib/python2.6/os.pyc
import errno # builtin
import posix # builtin
# /home/kk/Python/python26/lib/python2.6/posixpath.pyc matches /home/kk/Python/python26/lib/python2.6/posixpath.py
import posixpath # precompiled from /home/kk/Python/python26/lib/python2.6/posixpath.pyc
# /home/kk/Python/python26/lib/python2.6/stat.pyc matches /home/kk/Python/python26/lib/python2.6/stat.py
import stat # precompiled from /home/kk/Python/python26/lib/python2.6/stat.pyc
# /home/kk/Python/python26/lib/python2.6/genericpath.pyc matches /home/kk/Python/python26/lib/python2.6/genericpath.py
import genericpath # precompiled from /home/kk/Python/python26/lib/python2.6/genericpath.pyc
# /home/kk/Python/python26/lib/python2.6/warnings.pyc matches /home/kk/Python/python26/lib/python2.6/warnings.py
import warnings # precompiled from /home/kk/Python/python26/lib/python2.6/warnings.pyc
# /home/kk/Python/python26/lib/python2.6/linecache.pyc matches /home/kk/Python/python26/lib/python2.6/linecache.py
import linecache # precompiled from /home/kk/Python/python26/lib/python2.6/linecache.pyc
# /home/kk/Python/python26/lib/python2.6/types.pyc matches /home/kk/Python/python26/lib/python2.6/types.py
import types # precompiled from /home/kk/Python/python26/lib/python2.6/types.pyc
# /home/kk/Python/python26/lib/python2.6/UserDict.pyc matches /home/kk/Python/python26/lib/python2.6/UserDict.py
import UserDict # precompiled from /home/kk/Python/python26/lib/python2.6/UserDict.pyc
# /home/kk/Python/python26/lib/python2.6/_abcoll.pyc matches /home/kk/Python/python26/lib/python2.6/_abcoll.py
import _abcoll # precompiled from /home/kk/Python/python26/lib/python2.6/_abcoll.pyc
# /home/kk/Python/python26/lib/python2.6/abc.pyc matches /home/kk/Python/python26/lib/python2.6/abc.py
import abc # precompiled from /home/kk/Python/python26/lib/python2.6/abc.pyc
# /home/kk/Python/python26/lib/python2.6/copy_reg.pyc matches /home/kk/Python/python26/lib/python2.6/copy_reg.py
import copy_reg # precompiled from /home/kk/Python/python26/lib/python2.6/copy_reg.pyc
import encodings # directory /home/kk/Python/python26/lib/python2.6/encodings
# /home/kk/Python/python26/lib/python2.6/encodings/__init__.pyc matches /home/kk/Python/python26/lib/python2.6/encodings/__init__.py
import encodings # precompiled from /home/kk/Python/python26/lib/python2.6/encodings/__init__.pyc
# /home/kk/Python/python26/lib/python2.6/codecs.pyc matches /home/kk/Python/python26/lib/python2.6/codecs.py
import codecs # precompiled from /home/kk/Python/python26/lib/python2.6/codecs.pyc
import _codecs # builtin
# /home/kk/Python/python26/lib/python2.6/encodings/aliases.pyc matches /home/kk/Python/python26/lib/python2.6/encodings/aliases.py
import encodings.aliases # precompiled from /home/kk/Python/python26/lib/python2.6/encodings/aliases.pyc
# /home/kk/Python/python26/lib/python2.6/encodings/utf_8.pyc matches /home/kk/Python/python26/lib/python2.6/encodings/utf_8.py
import encodings.utf_8 # precompiled from /home/kk/Python/python26/lib/python2.6/encodings/utf_8.pyc
Python 2.6.2 (r262:71600, Aug 25 2009, 23:28:56)
[GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
# /home/kk/Python/python26/lib/python2.6/subprocess.pyc matches /home/kk/Python/python26/lib/python2.6/subprocess.py
import subprocess # precompiled from /home/kk/Python/python26/lib/python2.6/subprocess.pyc
# /home/kk/Python/python26/lib/python2.6/traceback.pyc matches /home/kk/Python/python26/lib/python2.6/traceback.py
import traceback # precompiled from /home/kk/Python/python26/lib/python2.6/traceback.pyc
import gc # builtin
dlopen("/home/kk/Python/python26/lib/python2.6/lib-dynload/time.so", 2);
import time # dynamically loaded from /home/kk/Python/python26/lib/python2.6/lib-dynload/time.so
dlopen("/home/kk/Python/python26/lib/python2.6/lib-dynload/select.so", 2);
import select # dynamically loaded from /home/kk/Python/python26/lib/python2.6/lib-dynload/select.so
dlopen("/home/kk/Python/python26/lib/python2.6/lib-dynload/fcntl.so", 2);
import fcntl # dynamically loaded from /home/kk/Python/python26/lib/python2.6/lib-dynload/fcntl.so
# /home/kk/Python/python26/lib/python2.6/pickle.pyc matches /home/kk/Python/python26/lib/python2.6/pickle.py
import pickle # precompiled from /home/kk/Python/python26/lib/python2.6/pickle.pyc
import marshal # builtin
# /home/kk/Python/python26/lib/python2.6/struct.pyc matches /home/kk/Python/python26/lib/python2.6/struct.py
import struct # precompiled from /home/kk/Python/python26/lib/python2.6/struct.pyc
dlopen("/home/kk/Python/python26/lib/python2.6/lib-dynload/_struct.so", 2);
import _struct # dynamically loaded from /home/kk/Python/python26/lib/python2.6/lib-dynload/_struct.so
# /home/kk/Python/python26/lib/python2.6/re.pyc matches /home/kk/Python/python26/lib/python2.6/re.py
import re # precompiled from /home/kk/Python/python26/lib/python2.6/re.pyc
# /home/kk/Python/python26/lib/python2.6/sre_compile.pyc matches /home/kk/Python/python26/lib/python2.6/sre_compile.py
import sre_compile # precompiled from /home/kk/Python/python26/lib/python2.6/sre_compile.pyc
import _sre # builtin
# /home/kk/Python/python26/lib/python2.6/sre_parse.pyc matches /home/kk/Python/python26/lib/python2.6/sre_parse.py
import sre_parse # precompiled from /home/kk/Python/python26/lib/python2.6/sre_parse.pyc
# /home/kk/Python/python26/lib/python2.6/sre_constants.pyc matches /home/kk/Python/python26/lib/python2.6/sre_constants.py
import sre_constants # precompiled from /home/kk/Python/python26/lib/python2.6/sre_constants.pyc
dlopen("/home/kk/Python/python26/lib/python2.6/lib-dynload/binascii.so", 2);
import binascii # dynamically loaded from /home/kk/Python/python26/lib/python2.6/lib-dynload/binascii.so
dlopen("/home/kk/Python/python26/lib/python2.6/lib-dynload/cStringIO.so", 2);
import cStringIO # dynamically loaded from /home/kk/Python/python26/lib/python2.6/lib-dynload/cStringIO.so
# clear __builtin__._
# clear sys.path
# clear sys.argv
# clear sys.ps1
# clear sys.ps2
# clear sys.exitfunc
# clear sys.exc_type
# clear sys.exc_value
# clear sys.exc_traceback
# clear sys.last_type
# clear sys.last_value
# clear sys.last_traceback
# clear sys.path_hooks
# clear sys.path_importer_cache
# clear sys.meta_path
# clear sys.flags
# clear sys.float_info
# restore sys.stdin
# restore sys.stdout
# restore sys.stderr
# cleanup __main__
# cleanup[1] cStringIO
# cleanup[1] encodings
# cleanup[1] site
# cleanup[1] subprocess
# cleanup[1] gc
# cleanup[1] select
# cleanup[1] abc
# cleanup[1] sre_constants
# cleanup[1] _codecs
# cleanup[1] _struct
# cleanup[1] _warnings
# cleanup[1] fcntl
# cleanup[1] zipimport
# cleanup[1] encodings.utf_8
# cleanup[1] codecs
# cleanup[1] pickle
# cleanup[1] signal
# cleanup[1] traceback
# cleanup[1] posix
# cleanup[1] encodings.aliases
# cleanup[1] exceptions
# cleanup[1] marshal
# cleanup[1] binascii
# cleanup[1] re
# cleanup[1] struct
# cleanup[1] sre_compile
# cleanup[1] _sre
# cleanup[1] sre_parse
# cleanup[2] copy_reg
# cleanup[2] posixpath
# cleanup[2] errno
# cleanup[2] _abcoll
# cleanup[2] types
# cleanup[2] genericpath
# cleanup[2] stat
# cleanup[2] warnings
# cleanup[2] UserDict
# cleanup[2] os.path
# cleanup[2] linecache
# cleanup[2] time
# cleanup[2] os
# cleanup sys
# cleanup __builtin__
# cleanup ints: 22 unfreed ints
# cleanup floats
kk@blissful:~/Download$

if it was windows, I could use the system's taskkill with switches /f
here is completely untested example.
This will close any running instance of firefox :)
Not sure about linux. I buried it long ago, though I plan to go back

import os
os.system("taskkill /F /IM firefox.exe")

Dear kk2628,
you're lucky, I have a live CD with Ubuntu, so I could test the program on ubuntu and I had the same problem. The problem is that the call to Popen with the argument shell=True creates 2 processes, a /bin/sh process and a /.../firefox process. The call to terminate() only kills the sh process. So I opened the subprocess with the command

child = sp.Popen(['firefox', '-p',  'foo', '-no-remote', url])

and it works. I don't know why the behaviour is different on my system (mandriva).
By the way, I don't think it's very useful to run python with the -v option.

Dear Gribouillis,

Yes, it works, thank you very much.

I am new to Python and does not know other ways to provide useful information for troubleshooting.

Thanks again.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.