I am building a Tkinter app with python that initializes multiple selenium webdrivers. The initial problem was that lots of chromedriver.exe instances were filling up user's memory, even after using driver.quit() (sometimes). So to get rid of this issue, when closing the tkinter app, I wrote this line os.system("taskkill /f /im chromedriver.exe /T"), that solves my problem, but, by using this, a command prompt instance is initiated that self kills almost instantly. The problem is that the user can see it and I find it kinda disturbing. Is there any way I could hide it? Or is there a workaround for my initial problem, that is user friendly?
Use both driver.close() and driver.quit() in your code in order to free memory.
driver.close()
driver.quit()
To reduce the memory footprint you should use ChromeDriver-Service:
First you start the service, then use it when creating new drivers, and finally stop the service before program exit.
Put the code below in chrome_factory.py and then:
on program start call chrome_factory.start_service()
to create new driver call chrome_factory.create_driver()
the service and drivers will be automatically stopped/quit at program exit.
Using this approach will result in only ever having single chromedriver.exe process.
# chrome_factory.py
import atexit
from os.path import expanduser
from typing import Optional
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
EXECUTABLE = expanduser("~/bin/chromedriver")
_chrome_service: Optional[Service] = None
def start_service():
global _chrome_service
_chrome_service = Service(EXECUTABLE)
_chrome_service.start()
atexit.register(_chrome_service.stop)
def create_driver() -> webdriver.Remote:
global _chrome_service
opts = webdriver.ChromeOptions()
opts.add_argument("--headless")
driver = webdriver.Remote(_chrome_service.service_url,
desired_capabilities=opts.to_capabilities())
atexit.register(driver.quit)
return driver
def main():
start_service()
for _ in range(20):
create_driver()
if __name__ == '__main__':
main()
Related
I need help with this code:
import webbrowser
chrome_path = 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe %s'
webbrowser.get(chrome_path).open('https://www.google.com/')
print('test browser')
it open chrome and visit the website, but don't print until I close the browser.
If I use this one:
import webbrowser
webbrowser.open('https://www.google.com/')
print('test browser')
It run default browser(brave), visit the website and print correctly.
How can I run X browser and print without need of close it to continue script?
You could create a new Thread and in that thread open the browser:
from threading import Timer
def open_browser():
webbrowser.open('https://www.google.com/')
Timer(1, open_browser).start()
print(“test”)
Everything that has to do with interaction of the browser should now be placed in def open_browser():
This code will set a timer for 1 millisecond and then execute the function within a seperate thread, so your code keeps executing.
I am using the undetected chromedriver in python selenium, my problem is that it always closes the window after ending the program.
For example I have a line of code like:
driver.get('www.google.com')
It obviously opens google but then immediately closes the window. When I use my own chromedriver, the window stays open and I can still surf on that window even when the program ends.
Any solutions?
I simply add a time.sleep(100) function, or kill the kernel
The original del method in the undetected chromedriver Chrome class quits the driver:
def __del__(self):
try:
self.service.process.kill()
except: # noqa
pass
self.quit()
Extend the class and override the del method. Keep the original stuff and comment out the self.quit() statement:
class MyUDC(uc.Chrome):
def __del__(self):
try:
self.service.process.kill()
except: # noqa
pass
# self.quit()
Now create your driver with
driver = MyUDC()
This is because the undetected chromedriver destructor terminates the chrome process when the class is destroyed.
Then you can extend the class and override the __del__ method
import undetected_chromedriver.v2 as uc
class My_Chrome(uc.Chrome):
def __del__(self):
pass
driver = My_Chrome()
driver.get('www.google.com')
I've written a script which opens Chromium and keeps it open for a set time, but I want to be able to set a proxy within the python script before opening Chromium. Is this possible? I've googled for some time, but I can't find how to do it.
Thanks in advance.
import os
from time import sleep
import webbrowser
import random
import time
timeDelay = random.randrange(57, 100)
def search():
#new browser object
chrome = webbrowser.get('chromium-browser')
#search engine startpoint
google = chrome.open_new("https://www.google.com")
if __name__ == "__main__":
sleep(0.5)
search()
time.sleep(timeDelay)
I have tried each of these solutions to no avail in attempt to achieve the same thing that was discussed on this thread. Yet that console window sticks around.
#kill console through .system
import os, sys
#webbrowsing modules
from selenium import webdriver
#function to launch browser in chrome
def launch_chrome(page):
browser = webdriver.Chrome(r'C:\Users\cj9250\AppData\Local\Continuum\anaconda3\chromedriver.exe')
browser.get(page)
return browser
url = "https://www.google.com/"
browser = launch_chrome(url)
#prints 'SUCCESS: The process "chromedriver.exe" with PID 9872 has been terminated.'
#in the terminal and leaves it open
os.system('taskkill /F /im chromedriver.exe')
quit()
#never gets to this print command
print('it quit')
#closes the browser as well
browser.service.stop()
sys.exit
print('it exit')
I should note that I am running my programs from batch files called by win+r similar to the way described in Automate the Boring Stuff. I also am running Python through Anaconda.
I'm working on a Django app. I'm using Selenium together with PhantomJS for testing.
I found today that I every time I terminate the test (which I do a lot when debugging,) the PhantomJS process is still alive. This means that after a debugging session I could be left with 200 zombie PhantomJS processes!
How do I get these PhantomJS processes to terminate when I terminate the Python debug process? If there's a time delay, that works too. (i.e. have them terminate if not used for 2 minutes, that would solve my problem.)
The usual setup is to quit the PhantomJS browser in the teardown method of the class. For example:
from django.conf import settings
from django.test import LiveServerTestCase
from selenium.webdriver.phantomjs.webdriver import WebDriver
PHANTOMJS = (settings.BASE_DIR +
'/node_modules/phantomjs/bin/phantomjs')
class PhantomJSTestCase(LiveServerTestCase):
#classmethod
def setUpClass(cls):
cls.web = WebDriver(PHANTOMJS)
cls.web.set_window_size(1280, 1024)
super(PhantomJSTestCase, cls).setUpClass()
#classmethod
def tearDownClass(cls):
screenshot_file = getattr(settings, 'E2E_SCREENSHOT_FILE', None)
if screenshot_file:
cls.web.get_screenshot_as_file(screenshot_file)
cls.web.quit()
super(PhantomJSTestCase, cls).tearDownClass()
If you do not use unittest test cases, you'll have to use the quit method yourself. You can use the atexit module to run code when the Python process terminates, for example:
import atexit
web = WebDriver(PHANTOMJS)
atexit.register(web.quit)