Find Outdated ChromeDriver Version Without Opening Executable (Python) - python

Essentially, I'm trying to find the ChromeDriver version without actually opening it. The reason for this is that I want to auto update the driver. I've sorted the code out for updating it.
The issue is that when I intentionally download an unsupported version to check my code works, it says "This driver only supports Chrome Version 86 and you're on 88.001.xyz" etc.
I was wondering if there was any way of reading the 86 from the ChromeDriver executable so that I can recognise it's not equal to 88 (my chrome browser version)? By doing this, it'll trigger a procedure to go and download the correct chromedriver.
I've attached my code for checking the chromedriver version. I've tried headless but I'm sure it doesn't work.
def get_chrome_version():
global browser_version_number
options = Options()
options.headless = True
browser_version_driver = webdriver.Chrome("chromedriver_win32/chromedriver.exe", chrome_options=options)
# browser_version_driver = webdriver.Chrome("chromedriver_win32/chromedriver.exe")
# browser_version_driver.set_window_position(-10000,0)
browser_version_number = (browser_version_driver.capabilities['browserVersion'])
browser_version_number = browser_version_number.split(".")[0]
chromedriverversion = browser_version_driver.capabilities['chrome']['chromedriverVersion'].split('.')[0]
print(browser_version_number)
print(chromedriverversion)
if browser_version_number != chromedriverversion:
update_chrome_version()
browser_version_driver.quit()

you could have your python script make a shell call to execute the command ./chromedriver --version (using the relevant path), then parse the result to find your current installed version.

Alrighty, so I found the solution. It all lied within the exception that was outputted in the terminal. Basically my thinking was to save the exception as string to a variable. Once I could do that, I could split it up and get what was needed from it. This was really easy to do since the ChromeDriver devs had this exception message:
Message: session not created: This version of ChromeDriver only supports Chrome version 86
Current browser version is 88.0.4324.xyz with binary path C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
So I needed to get the 86 to signify the ChromeDriver version and the 88 for the browser version. I've included the code below. If you have any questions, feel free to comment! I'm also aware that I may get crucified for the absolute spaghetti code I've written :). I just want to get something out and then clean up the tomato sauce off my shirt later!!
import logging
logger = logging.Logger('catch_all')
def get_chrome_version():
global browser_version_number
try:
browser_version_driver = webdriver.Chrome("chromedriver_win32/chromedriver.exe")
browser_version_number = (browser_version_driver.capabilities['browserVersion'])
browser_version_number = browser_version_number.split(".")[0]
chromedriverversion = browser_version_driver.capabilities['chrome']['chromedriverVersion'].split('.')[0]
print(browser_version_number)
print(chromedriverversion)
if browser_version_number != chromedriverversion:
update_chrome_version()
browser_version_driver.quit()
###############---------------REALLY IMPORTANT PART BELOW---------------###############
except Exception as e:
e = str(e) # Saves exception to a variable. Most importantly, converts to string to allow me to manipulate it.
print(e)
linesplit = e.split('This version of ChromeDriver only supports Chrome version ')[1]
checking_driverversion = linesplit.split('\n')[0]
print(checking_driverversion) # prints '86' which is my chromedriver right now
checking_browserversion = linesplit.split('\n')[1]
checking_browserversion = checking_browserversion.split('Current browser version is ')[1]
checking_browserversion = checking_browserversion.split('.')[0]
print(checking_browserversion) # prints '88' which is my browser version right now
browser_version_number = checking_browserversion
if checking_browserversion != checking_driverversion:
update_chrome_version()

Related

Save HAR file without browsermodproxy

I am using browsermobproxy and getting lots of errors that I don't want to deal with.
Is there a way to get a site's HAR file without using browsermobproxy?
If anyone's interested, here's the error I get from server.log
Running BrowserMob Proxy using LittleProxy implementation. To revert to the legacy implementation, run the proxy with the command-line option '--use-littleproxy false'.
Exception in thread "main" com.google.inject.internal.util.$ComputationException: java.lang.ExceptionInInitializerError
at com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:553)
at com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:419)
at com.google.inject.internal.util.$CustomConcurrentHashMap$ComputingImpl.get(CustomConcurrentHashMap.java:2041)
at com.google.inject.internal.FailableCache.get(FailableCache.java:50)
at com.google.inject.internal.ConstructorInjectorStore.get(ConstructorInjectorStore.java:49)
at com.google.inject.internal.ConstructorBindingImpl.initialize(ConstructorBindingImpl.java:125)
at com.google.inject.internal.InjectorImpl.initializeBinding(InjectorImpl.java:507)
at com.google.inject.internal.AbstractBindingProcessor$Processor$1.run(AbstractBindingProcessor.java:159)
at com.google.inject.internal.ProcessedBindingData.initializeBindings(ProcessedBindingData.java:44)
at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:122)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:106)
at com.google.inject.Guice.createInjector(Guice.java:95)
at com.google.inject.Guice.createInjector(Guice.java:72)
at com.google.inject.Guice.createInjector(Guice.java:62)
at net.lightbody.bmp.proxy.Main.main(Main.java:47)
Caused by: java.lang.ExceptionInInitializerError
at com.google.inject.internal.cglib.reflect.$FastClassEmitter.<init>(FastClassEmitter.java:67)
at com.google.inject.internal.cglib.reflect.$FastClass$Generator.generateClass(FastClass.java:72)
at com.google.inject.internal.cglib.core.$DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at com.google.inject.internal.cglib.core.$AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at com.google.inject.internal.cglib.reflect.$FastClass$Generator.create(FastClass.java:64)
at com.google.inject.internal.BytecodeGen.newFastClass(BytecodeGen.java:207)
at com.google.inject.internal.DefaultConstructionProxyFactory.create(DefaultConstructionProxyFactory.java:53)
at com.google.inject.internal.ProxyFactory.create(ProxyFactory.java:153)
at com.google.inject.internal.ConstructorInjectorStore.createConstructor(ConstructorInjectorStore.java:89)
at com.google.inject.internal.ConstructorInjectorStore.access$000(ConstructorInjectorStore.java:28)
at com.google.inject.internal.ConstructorInjectorStore$1.create(ConstructorInjectorStore.java:36)
at com.google.inject.internal.ConstructorInjectorStore$1.create(ConstructorInjectorStore.java:32)
at com.google.inject.internal.FailableCache$1.apply(FailableCache.java:39)
at com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:549)
... 14 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module #1593948d
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
at com.google.inject.internal.cglib.core.$ReflectUtils$2.run(ReflectUtils.java:56)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
at com.google.inject.internal.cglib.core.$ReflectUtils.<clinit>(ReflectUtils.java:46)
... 28 more
And here's my code:
from browsermobproxy import Server
server = Server("C:\\Users\\USER\\Desktop\\har_export\\browsermob-proxy-2.1.4\\bin\\browsermob-proxy.bat")
server.start()
proxy = server.create_proxy()
from selenium import webdriver
profile = webdriver.FirefoxProfile()
profile.set_proxy(proxy.selenium_proxy())
driver = webdriver.Firefox(firefox_profile=profile)
proxy.new_har("google")
driver.get("http://www.google.co.in")
proxy.har # returns a HAR JSON blob
server.stop()
driver.quit()
Any suggestions/solutions would be appreciated.
I believe you are running your browsermob proxy under the latest version of JRE. Since version 16 there are some limitation introduced to the refelction mechanism that make the code that used to work in previous versions not working any more.
So the easiest solution would be downgrade your JRE. According to this thread, JRE 11 would work for you.

browser_switcher_service.cc(238)] XXX Init() error with Python Selenium Script with Chrome for Web Scraping

I was using a small python script along with chrome drivers to download manga from Mangafox. It used to run fine until a few days ago when I updated the Chrome Browser. The following error is shown every time I try it now:
[14664:14280:0420/202509.245:ERROR:browser_switcher_service.cc(238)] XXX Init()
[14664:14280:0420/202509.678:ERROR:device_event_log_impl.cc(162)] [20:25:09.679] Bluetooth: bluetooth_adapter_winrt.cc:1186 Getting Radio failed. Chrome will be unable to change the power state by itself.
[14664:14280:0420/202509.695:ERROR:device_event_log_impl.cc(162)] [20:25:09.696] Bluetooth: bluetooth_adapter_winrt.cc:1264 OnPoweredRadioAdded(), Number of Powered Radios: 1
[14664:14280:0420/202509.696:ERROR:device_event_log_impl.cc(162)] [20:25:09.696] Bluetooth: bluetooth_adapter_winrt.cc:1283 OnPoweredRadiosEnumerated(), Number of Powered Radios: 1
I have used the selenium module with chrome drivers. I have tried updating my web drivers, tried making the code loop or sleep until the web-page loads completely.
My Code is as follows:
from selenium import webdriver
import os
import urllib.request
Main = 'https://ww3.mangafox.online/'
Name = str(input('Enter Name of Manga as on \'ww3.Mangafox.online\': '))
Name = Name.replace(' ', '-')
Name = Name.replace('\'', '-')
driver = webdriver.Chrome(r'C:\Users\freak\Assignments\SDP\Drivers\chromedriver.exe')
driver.get(Main + Name)
Tags = driver.find_elements_by_tag_name('a')
List = []
for Tag in Tags:
List.append(str(Tag.get_attribute('href')))
dir = os.path.join('C:\\','Users', 'freak', 'Assignments', 'SDP', 'Test', Name.replace('-', '_'))
print('Checking the existence of folder; %s' % dir)
if not os.path.exists(dir):
print('Folder not found. Attempting to create folder: %s' % dir)
os.mkdir(dir)
print('Folder successfully created')
Index = []
for i, element in enumerate(List):
if (str(Name) + '/chapter') in element:
Index.append(i)
Chapters = []
After this part is just a loop I used to download the images. But for some reason, an error is shown and the list made for Tags remains empty. The driver.find_elements_by_tag_name('a') fails completely.
These error messages...
[14664:14280:0420/202509.245:ERROR:browser_switcher_service.cc(238)] XXX Init()
[14664:14280:0420/202509.678:ERROR:device_event_log_impl.cc(162)] [20:25:09.679] Bluetooth: bluetooth_adapter_winrt.cc:1186 Getting Radio failed. Chrome will be unable to change the power state by itself.
[14664:14280:0420/202509.695:ERROR:device_event_log_impl.cc(162)] [20:25:09.696] Bluetooth: bluetooth_adapter_winrt.cc:1264 OnPoweredRadioAdded(), Number of Powered Radios: 1
[14664:14280:0420/202509.696:ERROR:device_event_log_impl.cc(162)] [20:25:09.696] Bluetooth: bluetooth_adapter_winrt.cc:1283 OnPoweredRadiosEnumerated(), Number of Powered Radios: 1
...implies that the on_init_ method failed in std::make_unique<base::ScopedClosureRunner>(std::move(on_init)).
Analysis
These errors are defined in bluetooth_adapter_winrt.cc as follows:
Getting Radio failed. Chrome will be unable to change the power state by itself:
void BluetoothAdapterWinrt::OnGetRadio(base::ScopedClosureRunner on_init,
ComPtr<IRadio> radio) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (radio) {
radio_ = std::move(radio);
radio_was_powered_ = GetState(radio_.Get()) == RadioState_On;
radio_state_changed_token_ = AddTypedEventHandler(
radio_.Get(), &IRadio::add_StateChanged,
base::BindRepeating(&BluetoothAdapterWinrt::OnRadioStateChanged,
weak_ptr_factory_.GetWeakPtr()));
if (!radio_state_changed_token_)
BLUETOOTH_LOG(ERROR) << "Adding Radio State Changed Handler failed.";
return;
}
// This happens within WoW64, due to an issue with non-native APIs.
BLUETOOTH_LOG(ERROR)
<< "Getting Radio failed. Chrome will be unable to change the power "
"state by itself.";
Number of Powered Radios: 1:
void BluetoothAdapterWinrt::OnPoweredRadioAdded(IDeviceWatcher* watcher,
IDeviceInformation* info) {
if (++num_powered_radios_ == 1)
NotifyAdapterPoweredChanged(true);
BLUETOOTH_LOG(ERROR) << "OnPoweredRadioAdded(), Number of Powered Radios: "
<< num_powered_radios_;
}
void BluetoothAdapterWinrt::OnPoweredRadioRemoved(
IDeviceWatcher* watcher,
IDeviceInformationUpdate* update) {
if (--num_powered_radios_ == 0)
NotifyAdapterPoweredChanged(false);
BLUETOOTH_LOG(ERROR) << "OnPoweredRadioRemoved(), Number of Powered Radios: "
<< num_powered_radios_;
}
void BluetoothAdapterWinrt::OnPoweredRadiosEnumerated(IDeviceWatcher* watcher,
IInspectable* object) {
BLUETOOTH_LOG(ERROR)
<< "OnPoweredRadiosEnumerated(), Number of Powered Radios: "
<< num_powered_radios_;
// Destroy the ScopedClosureRunner, triggering the contained Closure to be
// run. Note this may destroy |this|.
DCHECK(on_init_);
on_init_.reset();
}
Deep Dive
These errors are the direct impact of the changes incorporated with google-chrome as per the details within the discussion in Chrome no longer accepts certificates that fallback to common name
Solution
Ensure that:
Selenium is upgraded to current levels Version 3.141.59.
ChromeDriver is updated to current ChromeDriver v84.0 level.
Chrome is updated to current Chrome Version 84.0 level. (as per ChromeDriver v84.0 release notes)
If your base Web Client version is too old, then uninstall it and install a recent GA and released version of Web Client.
Additional considerations
However it was observed that this error can be supressed by running Chrome as root user (administrator) on Linux, but that would be a deviation from the documentation in ChromeDriver - WebDriver for Chrome where it is mentioned:
A common cause for Chrome to crash during startup is running Chrome as root user (administrator) on Linux. While it is possible to work around this issue by passing '--no-sandbox' flag when creating your WebDriver session, i.e. the ChromeDriver session as such a configuration is unsupported and highly discouraged.
Ideally, you need to configure your environment to run Chrome as a regular user instead.
Suppressing the error
Finally, as per the documentation in Selenium Chrome Driver: Resolve Error Messages Regarding Registry Keys and Experimental Options these error logs can be supressed by adding the argument:
excludeSwitches: ['enable-logging']
So your effective code block will be:
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-logging"])
driver = webdriver.Chrome(options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
driver.get("https://www.google.com/")
Have you tried switching to the Firefox driver instead?
https://github.com/mozilla/geckodriver/releases
You'd just have to update your code:
driver = webdriver.Firefox(executable_path='/path/to/driver')

Getting the version of Mozilla on my device and comparing with the latest version. Python, Windows

I have a task compare the latest version of Mozilla with the version on current device.
I wrote the code to get numeric value of the latest version.
Here is this code:
import requests
def get_ver_from_url():
r = requests.get('https://download.mozilla.org/?product=firefox-latest&os=win&lang=en-US',
allow_redirects=False)
base_usl = r.headers['Location']
delimiter = base_usl.split('/')[-4]
print delimiter
return delimiter
get_ver_from_url()
And now I want to get numeric value of mine version of Mozilla to compare it.
How can I execute it in easiest way?
In this page,It show your that how to see the version of Firefox.
In cmd,input firefox -v|more can get the version of it(after you enter the folder which Firefox install).
But I failed to save the output to a variable.
(BTW,If you want to use firefox -v|more in any folder,you should add C:\Program Files\Mozilla Firefox to your system PATH)
Admittedly, jizhihaoSAMA's method does seem easier (using subprocess.Popen). Nevertheless, here is another method utilising win32api:
import requests, win32api
def get_ver_from_url():
r = requests.get('https://download.mozilla.org/?product=firefox-latest&os=win&lang=en-US',
allow_redirects=False)
base_usl = r.headers['Location']
delimiter = base_usl.split('/')[-4]
print(delimiter)
return float(delimiter) # You probably want this as a float or decimal, not a string
def get_installed_version():
firefox_filepath = r"C:\Program Files\Mozilla Firefox\firefox.exe"
version_info = win32api.GetFileVersionInfo(firefox_filepath, "\\")
product_version = version_info["ProductVersionMS"] # There is also ProductVersionLS to get the least significant 32 bits of the version number, but that seems unnecessary
product_version = float(f"{product_version >> 16}.{product_version & 0xFFFF}")
return product_version
latest_version = get_ver_from_url()
installed_version = get_installed_version()
print("Installed version:", installed_version)
print("Latest version:", latest_version)
if latest_version > installed_version:
print("Installed version is out of date!")
Output:
74.0
Installed version: 73.0
Latest version: 74.0
Installed version is out of date!

Python Selenium Firefox Custom Profiles Save

I just started learning selenium with python
from selenium import webdriver
MY_PROFILE = "D:\\FIREFOX_PROFILE"
FFP = webdriver.FirefoxProfile(MY_PROFILE)
print(FFP.profile_dir)
# OUTPUT: C:\Users\ABC\AppData\Local\Temp\****\***
# But it should be OUTPUT: D:\FIREFOX_PROFILE
DRIVER = webdriver.Firefox(firefox_profile = FFP)
print(FFP.profile_dir)
# OUTPUT: C:\Users\ABC\AppData\Local\Temp\****\***
# But it should be OUTPUT: D:\FIREFOX_PROFILE
I want to save my profile somewhere so that I can use it later on.
I also tried creating RUN -> firefox.exe -p and creating a new profile (I can't use the created profile). Nothing works.
I am using:
Selenium Version: 2.53.6
Python Version: 3.4.4
Firefox Version: Various(49.0.2, 45, 38 etc)
I searched in Google but I can't solve it. Is there any way to save the profile?
You need to take help of os module in python
import os
there you get functions (like .getcwd() ) to described in Files and Directories.
then use,
p = webdriver.FirefoxProfile()
p.set_preference('browser.download.folderList', 2 )
p.set_preference('browser.download.manager.showWhenStarting', false)
p.set_preference('browser.download.dir', os.getcwd())
p.set_preference('browser.helperApps.neverAsk.saveToDisk', 'text/csv/xls')
driver = webdriver.Firefox(p)
in short you can do so,
profile.set_preference("browser.helperApps.neverAsk.openFile","text/csv,application/x-msexcel,application/excel,application/x-excel,application/vnd.ms-excel,image/png,image/jpeg,text/html,text/plain,application/msword,application/xml")
possible duplicate of Setting selenium to use custom profile, but it keeps opening with default

Python 2.7 changing default browser for webbrower.open

I am trying to open a page a wrote and saved to a local server. Everything is great but it defaults to opening in IE instead of Chrome. Chrome is my default browser and couldn't find any helpful tips online.
Sample code:
import webbrowser
webbrowser.open('192.168.1.254:1337/SmartFormTest1.php')
Thanks in advance!
Alright, found the issue. My browser was correctly defaulted to chrome, the issue is the webbrowser.py file. Lines 539-563 read:
if sys.platform[:3] == "win":
class WindowsDefault(BaseBrowser):
def open(self, url, new=0, autoraise=True):
try:
os.startfile(url)
except WindowsError:
# [Error 22] No application is associated with the specified
# file for this operation: '<URL>'
return False
else:
return True
_tryorder = []
_browsers = {}
# First try to use the default Windows browser
register("windows-default", WindowsDefault)
# Detect some common Windows browsers, fallback to IE
iexplore = os.path.join(os.environ.get("PROGRAMFILES", "C:\\Program Files"),
"Internet Explorer\\IEXPLORE.EXE")
for browser in ("firefox", "firebird", "seamonkey", "mozilla",
"netscape", "opera", iexplore):
if _iscommand(browser):
register(browser, None, BackgroundBrowser(browse()
All I needed to do was add "chrome" to the list of for browser in (list).
Following the documentation, there are a few directions you can go with this:
Set the environment variable BROWSER
Use webbrowser.get('chrome') to get a controller instance of Chrome, then use that to do your browsing
Check your setup -- are you positive that your default browser is set properly? Does it appear under the "Internet" icon in your Start menu?
In Windows, the following code works for me.
chrome_path = '"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" %s'
webbrowser.get(chrome_path).open('google.com')
My browser was correctly defaulted to brave, just change it in the webbrowser.py file. Lines 539-563
In Line 540, just change the OS path to the desired browser you want to use. For Brave just change the path given to the iexplorer variable
like this:
iexplore = os.path.join(os.environ.get("PROGRAMFILES", "C:\\Program Files"),
"BraveSoftware\\Brave-Browser\\Application\\brave.EXE")

Categories