I'm using Python 3.9 on macOS. I'm trying to start using webbot, but every time I try, I get this error:
selenium.common.exceptions.SessionNotCreatedException: Message: session not created
exception: Missing or invalid capabilities
(Driver info: chromedriver=2.39.562713
(dd642283e958a93ebf6891600db055f1f1b4f3b2),platform=Mac OS X 10.14.6 x86_64)
I'm using macOS version 10.4 because I use 32 bit software. The part that really puzzles me is why is says chromedriver=2.39.562713. According to the pip, the driver's version is 103.0.5060.53. If I import selenium and try the command help(selenium), towards the end of the output, I get:
VERSION
4.3.0
Where does this lower version come from? I'm pretty sure that's why I have "missing or invalid capabilities." If I start selenium with:
from selenium import webdriver
driver = webdriver.Chrome()
It starts Chrome as expected. Obviously I'm missing something.
I used to start webbot with:
from webbot import Browser
driver = Browser()
But then, just to be sure, I changed it to:
from webbot import Browser
driver = Browser(True, None, '/usr/local/bin/')
'/usr/local/bin/' being the location of a chrome webdriver installed by brew that is explicitly version 103. No difference.
Solution
The approved response was not the solution, but it led me to the solution.
My version of webbot is the latest, but it has a very different __init__ method:
def __init__(self, showWindow=True, proxy=None , downloadPath:str=None):
Upon further inspection, I saw that the driverPath attribute (that I had tried to use earlier) was completely gone by design. So I decided to print the value of the inner variable driverpath inside the __init__ method. This returned the following:
project_root/virtualenvironment/lib/python3.9/site-packages/webbot/drivers/chrome_mac
There was my guilty party! I renamed that executable and in its place put a symbolic link to the correct binary. That worked.
driver = Browser(True, None, '/usr/local/bin/')
actually sets the downloadPath, not the driverPath. Use the parameter name explicitly
driver = Browser(driverPath='/usr/local/bin/')
From webbot.py
class Browser:
def __init__(self, showWindow=True, proxy=None , downloadPath:str=None, driverPath:str=None, arguments=["--disable-dev-shm-usage","--no-sandbox"]):
if driverPath is not None and isinstance(driverPath,str):
driverPath = os.path.abspath(driverPath)
if(not os.path.isdir(driverPath)):
raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), driverPath)
if driverPath is None:
driverfilename = ''
if sys.platform == 'linux' or sys.platform == 'linux2':
driverfilename = 'chrome_linux'
elif sys.platform == 'win32':
driverfilename = 'chrome_windows.exe'
elif sys.platform == 'darwin':
driverfilename = 'chrome_mac'
driverPath = os.path.join(os.path.split(__file__)[0], 'drivers{0}{1}'.format(os.path.sep, driverfilename))
self.driver = webdriver.Chrome(executable_path=driverPath, options=options)
If driverPath is None it will set to
/{parent_folder_abs_path}/drivers/chrome_mac or /{parent_folder_abs_path}/drivers/, I'm guessing you have an older chromedriver version there.
Related
I have a simple python3.9 rumps app, roughly following the documented example https://rumps.readthedocs.io/en/latest/examples.html.
main.py:
import rumps
class SiMenuBarApp(rumps.App):
def __init__(self):
super(SiMenuBarApp, self).__init__("SiProdHacks")
self.menu = ["Item1"]
#rumps.clicked("Item1")
def item_one(self, _):
print("Hi Si!")
rumps.notification("SiProdHacks", "Keeping Si's Brain Free since 2021", "KAPOWIE!")
if __name__ == '__main__':
app = SiMenuBarApp()
app.icon = "happyicon.png"
app.run()
It runs fine, but when I click the menu bar item1, it prints my console message, but no notification occurs.
I am using python 3.9.0, rumps=0.3.0, iTerm and Mac OS 10.15.7 (Catalina).
Console output is:
❯ pipenv run python main.py
Hi Si!
Ok, I did some more digging on this, and discovered the debug mode of rumps:
import rumps
rumps.debug_mode(True)
which added the following to the output:
In this case there is no file at "/Users/simonrowland/.local/share/virtualenvs/si-menu-productivity-mlyLc7OG/bin/Info.plist"
Running the following command should fix the issue:
/usr/libexec/PlistBuddy -c 'Add :CFBundleIdentifier string "rumps"' /Users/simonrowland/.local/share/virtualenvs/si-menu-productivity-mlyLc7OG/bin/Info.plist
Running the suggested command:
/usr/libexec/PlistBuddy -c 'Add :CFBundleIdentifier string "rumps"' ${PATH_TO_VENV_BIN_DIR}/bin/Info.plist
Made it work!
After upgrading from python 3.8.0 to python 3.9.1, the tremc front-end of transmission bitTorrent client is throwing decodestrings is not an attribute of base64 error whenever i click on a torrent entry to check the details.
My system specs:
OS: Arch linux
kernel: 5.6.11-clear-linux
base64.encodestring() and base64.decodestring(), aliases deprecated since Python 3.1, have been removed.
use base64.encodebytes() and base64.decodebytes()
So i went to the site-packages directory and with ripgrep tried searching for the decodestring string.
rg decodestring
paramiko/py3compat.py
39: decodebytes = base64.decodestring
Upon examining the py3compat.py file,i found this block:
PY2 = sys.version_info[0] < 3
if PY2:
string_types = basestring # NOQA
text_type = unicode # NOQA
bytes_types = str
bytes = str
integer_types = (int, long) # NOQA
long = long # NOQA
input = raw_input # NOQA
decodebytes = base64.decodestring
encodebytes = base64.encodestring
So decodebytes have replaced(aliased) decodestring attribute of base64 for python version >= 3
This must be a new addendum because tremc was working fine in uptil version 3.8.*.
Opened tremc script, found the erring line (line 441), just replaced the attribute decodestring with decodebytes.A quick fix till the next update.
PS: Checked the github repository, and there's a pull request for it in waiting.
If you don't want to wait for the next release and also don't want to hack the way i did, you can get it freshly build from the repository, though that would be not much of a difference than my method
Below error message:
device = XMLConverter(rsrcmgr, retstr, laparams=laparams, codec=codec)
TypeError: __init__() got an unexpected keyword argument 'codec'
Original Code:
rsrcmgr = PDFResourceManager()
retstr = BytesIO()
codec = 'utf-8'
laparams = LAParams()
device = XMLConverter(rsrcmgr, retstr, laparams=laparams, codec=codec)
This is surprisingly working fine in my project setup (python 3.5.3) but not in the new setup (python 3.7.4). Not sure if the this is anyways a problem or if a new version of XMLConverter is now available
As suspected by chris, this issue is due to version mismatch. 2019 version of pdfminer doesn't have keyword codec in the method. So I installed the older version of pdfminer 20181108 which is used in my project as well. Now the code runs without any error
I have the following code to run tests in various browsers. Chrome of course works correctly on the machine I am wanting to run these tests on, however, Firefox, IE, and Edge do not. Is this the right way to go about this? I would prefer not to have to have a file I have to download and change every couple of months when the browsers update.
def __init__(self, browser: str = TESTING_BROWSER, home: str = BASE_URL):
"""Hooray for inits."""
if browser.lower() == "ie":
webdriver.Ie.__init__(self, IEDriverManager().install())
elif browser.lower() == 'edge':
webdriver.Edge().__init__(self, EdgeDriverManager().install())
elif browser.lower() == "firefox":
webdriver.Firefox.__init__(self, GeckoDriverManager().install())
else:
chrome_options = Options()
if os.environ.get('RUN_HEADLESS') == 'True':
chrome_options.add_argument('--headless')
chrome_options.add_argument("--disable-extensions")
chrome_options.add_argument("--disable-gpu")
webdriver.Chrome.__init__(self, ChromeDriverManager().install(), chrome_options=chrome_options)
else:
webdriver.Chrome.__init__(self, ChromeDriverManager().install())
As a side note when I try and run Firefox, I am getting the following error:
NotADirectoryError: [Errno 20] Not a directory: '/Users/me/.wdm/geckodriver/v0.24.0/macos/geckodriver'
I have tried adding executable_path=path to geckodriver and that is not working either.
So RTD wins again:
webdriver.Firefox.__init__(self, executable_path=GeckoDriverManager().install())
For those interested, the documentation to webdriver_manager is here
I would like to query Windows using a file extension as a parameter (e.g. ".jpg") and be returned the path of whatever app windows has configured as the default application for this file type.
Ideally the solution would look something like this:
from stackoverflow import get_default_windows_app
default_app = get_default_windows_app(".jpg")
print(default_app)
"c:\path\to\default\application\application.exe"
I have been investigating the winreg builtin library which holds the registry infomation for windows but I'm having trouble understanding its structure and the documentation is quite complex.
I'm running Windows 10 and Python 3.6.
Does anyone have any ideas to help?
The registry isn't a simple well-structured database. The Windows
shell executor has some pretty complex logic to it. But for the simple cases, this should do the trick:
import shlex
import winreg
def get_default_windows_app(suffix):
class_root = winreg.QueryValue(winreg.HKEY_CLASSES_ROOT, suffix)
with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, r'{}\shell\open\command'.format(class_root)) as key:
command = winreg.QueryValueEx(key, '')[0]
return shlex.split(command)[0]
>>> get_default_windows_app('.pptx')
'C:\\Program Files\\Microsoft Office 15\\Root\\Office15\\POWERPNT.EXE'
Though some error handling should definitely be added too.
Added some improvements to the nice code by Hetzroni, in order to handle more cases:
import os
import shlex
import winreg
def get_default_windows_app(ext):
try: # UserChoice\ProgId lookup initial
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\{}\UserChoice'.format(ext)) as key:
progid = winreg.QueryValueEx(key, 'ProgId')[0]
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'SOFTWARE\Classes\{}\shell\open\command'.format(progid)) as key:
path = winreg.QueryValueEx(key, '')[0]
except: # UserChoice\ProgId not found
try:
class_root = winreg.QueryValue(winreg.HKEY_CLASSES_ROOT, ext)
if not class_root: # No reference from ext
class_root = ext # Try direct lookup from ext
with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, r'{}\shell\open\command'.format(class_root)) as key:
path = winreg.QueryValueEx(key, '')[0]
except: # Ext not found
path = None
# Path clean up, if any
if path: # Path found
path = os.path.expandvars(path) # Expand env vars, e.g. %SystemRoot% for ext .txt
path = shlex.split(path, posix=False)[0] # posix False for Windows operation
path = path.strip('"') # Strip quotes
# Return
return path