Webbrowser opens two windows instead of two tabs - python

I'm trying to open two websites in two tabs in my web browser. What actually happens is that two separate web browser windows are opened.
import webbrowser
webbrowser.open_new('https://www.msn.com')
webbrowser.open_new_tab('https://www.aol.com/')

The issue is likely that browser hasn't finished opening by the time you ask for a new tab. The docs do state that if no browser is open open_new_tab() acts as open_new(), which is why you are seeing two browsers.
I suggest putting a small delay between the calls:
import webbrowser
import time
webbrowser.open_new(url1)
time.sleep(1)
webbrowser.open_new_tab(url2)
Your other option is to poll the running processes and wait until the first instance of the browser appears before asking for a new tab.

Related

Open tabs one after another with Webbrower

I am trying run a script to open multiple tabs
import webbrowser
import time
browser = webbrowser.get('"C:Program Files\BraveSoftware\Brave-Browser\Application\Brave.exe" %s')
browser.open_new_tab("www.gmail.com")
browser.open_new_tab("google.com")
print("done")
It would only put one tab and then stop until I close the whole browser and then opens the browser again with the tab in second line.
What am I doing wrong?
It works fine when the browser is already open.

Python3, Selenium, Chromedriver console window

I've a made a selenium test using python3 and selenium library.
I've also used Tkinter to make a GUI to put some input on (account, password..).
I've managed to hide the console window for python by saving to the .pyw extension; and when I make an executable with my code, the console doesn't show up even if it's saved with .py extension.
However, everytime the chromedriver starts, it also starts a console window, and when the driver exists, this window does not.
so in a loop, i'm left with many webdriver consoles.
Is there a work around this to prevent the driver from launching a console everytime it runs ?
I hated dealing with this in selenium until I remembered that this was an obvious use case for context managers just like the usage of open.
I did find out that selenium is about to add this officially to their package in this pull request
Until this is officially added, this snippet should give you the functionality you need to get things going :)
import contextlib
#contextlib.contextmanager
def Chrome(*args, **kwargs):
webdriver = webdriver.Chrome(*args, **kwargs)
try:
yield webdriver
finally:
webdriver.quit()
with Chrome() as driver:
# whatever you're planning on doing goes here
driver.close() and driver.quit() are two different methods for closing the browser session in Selenium WebDriver.
driver.close() - It closes the the browser window on which the focus is set.
driver.quit() – It basically calls driver.dispose method which in turn closes all the browser windows and ends the WebDriver session gracefully.
You should use driver.quit whenever you want to end the program. It will close all opened browser window and terminates the WebDriver session. If you do not use driver.quit at the end of program, WebDriver session will not close properly and files would not be cleared off memory. This may result in memory leak errors.

Python Selenium send request and avoid "Waiting for (website) ...."

I am launching several requests on different tabs. While one tab loads I will iteratively go to other tabs and see whether they have loaded correctly. The mechanism works great except for one thing: a lot of time is wasted "Waiting for (website)..."
The way in which I go from one tab to the other is launching an exception whenever a key element that I have to find is missing. But, in order to check for this exception (and therefore to proceed on other tabs, as it should do) what happens is that I have to wait for the request to end (so for the message "Waiting for..." to disappear).
Would it be possible not to wait? That is, would it be possible to launch the request via browser.get(..) and then immediately change tab?
Yes you can do that. You need to change the pageLoadStrategy of the driver. Below is an example of firefox
import time
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium import webdriver
cap = DesiredCapabilities.FIREFOX
cap["pageLoadStrategy"] = "none"
print(DesiredCapabilities.FIREFOX)
driver = webdriver.Firefox(capabilities=cap)
driver.get("http://tarunlalwani.com")
#execute code for tab 2
#execute code for tab 3
Nothing will wait now and it is up to you to do all the waiting. You can also use eager instead of none

Multi-threading in selenium python

I am working on a project which needs bit automation and web-scraping for which I am using Selenium and BeautifulSoup (python2.7).
I want to open only one instance of a web browser and login to a website, keeping that session, I am trying to open new tabs which will be independently controlled by threads, each thread controlling a tab and performing their own task. How should I do it? An example code would be nice. Well here's my code:
def threadFunc(driver, tabId):
if tabId == 1:
#open a new tab and do something in it
elif tabId == 2:
#open another new tab with some different link and perform some task
.... #other cases
class tabThreads(threading.Thread):
def __init__(self, driver, tabId):
threading.Thread.__init__(self)
self.tabID = tabId
self.driver = driver
def run(self):
print "Executing tab ", self.tabID
threadFunc(self.driver, self.tabID)
def func():
# Created a main window
driver = webdriver.Firefox()
driver.get("...someLink...")
# This is the part where i am stuck, whether to create threads and send
# them the same web-driver to stick with the current session by using the
# javascript call "window.open('')" or use a separate for each tab to
# operate on individual pages, but that will open a new browser instance
# everytime a driver is created
thread1 = tabThreads(driver, 1)
thread2 = tabThreads(driver, 2)
...... #other threads
I am open to suggestions for using any other module, if needed
My understanding is that Selenium drivers are not thread-safe. In the WebDriver spec, the Thread Safety section is empty...which I take to mean they have not addressed the topic at all. https://www.w3.org/TR/2012/WD-webdriver-20120710/#thread-safety
So while you could share the driver reference with multiple threads and make calls to the driver from multiple threads, there is no guarantee that the driver will be able to handle multiple asynchronous calls correctly.
Instead, you must either synchronize calls from multiple threads to ensure one is completed before the next starts, or you should have just one thread making Selenium API calls...potentially handling commands from a queue that is filled by multiple other threads.
Also, see Can Selenium use multi threading in one browser?
I you are using the script to automatically submit forms (simply said doing GET and POST requests), I would recommend you to look at requests. You can easily capture Post requests from your Browser (Network tab in Developer Pane on both Firefox and Chrome), and submit them. Something like:
session = requests.session()
response = session.get('https://stackoverflow.com/')
soup = BeautifulSoup(response.text)
and even POST data like:
postdata = {'username':'John','password':password}
response=session.post('example.com',data=postdata,allow_redirects=True)
It can be easily threaded, Multiple times faster than using selenium, the only problem is there is no JavaScript or Form support, so you need to do it the old fashioned way.
EDIT:
Also take a look at ThreadPoolExecutor

How to close the existing browser tab using the Python webbrowser package

Using Python webbrowser package I can open a new tab with a specified URL. Is there a way to close this tab? I referred the below official docs and nothing related to close action is mentioned.
Python webbrowser package doc: https://docs.python.org/3/library/webbrowser.html
You can use pyautogui to close the browser tab when your task is fulfilled.
import time,webbrowser, pyautogui
def open_close(url="https://www.python.org/"):
webbrowser.open(url)
time.sleep(20)
pyautogui.hotkey('ctrl', 'w')
print("tab closed")
No, webbrowser doesn't have methods to close tabs nor browser itself as you may see in its documentation page:
https://docs.python.org/2/library/webbrowser.html
You could
Use a hotkey using the pykeyboard library which you can read about at https://github.com/SavinaRoja/PyUserInput
or the keyboard library at https://github.com/boppreh/keyboard
Another (but probably worse) option is:
You may use a "taskkill" command like
import os
os.system("taskkill /im chrome.exe /f")
However, this will just kill all processes and close the chosen program (in this case chrome.exe)
(This also may delete data from the browser, f.eks. you lose all you're windows even tho you have chosen in settings to save them for next time you open your browser)
u can close the tab by driver.close if u are using selenium package

Categories