Zoom browser window in python Selenium/Firefox - python

I am using python to interact with webpages via selenium. I am using the geckodriver Firefox driver (not interested in Chrome solutions).
I want to zoom the browser window, equivalent to pressing ctrl+- (or cmd+- on Mac OS).
Granted, there are lots of questions on this topic. I have tried to do my due diligence in digging through them before posting here. The following are solutions that do not work for me (let driver be a WebDriver instance running with geckodriver):
No effect:
driver.execute_script("document.body.style.zoom='zoom 90%'")
from selenium.webdriver.common.keys import Keys
body = driver.find_element_by_tag_name('body')
body.send_keys(Keys.COMMAND, Keys.SUBTRACT)
from selenium.webdriver.common.action_chains import ActionChains
actor = ActionChains(driver)
actor.key_down(Keys.COMMAND).key_down(Keys.SUBTRACT).perform()
Wrong effect:
driver.execute_script("document.body.style.transform='scale(0.9)'")
driver.execute_script("document.body.style.MozTransform='scale(0.9)'")
Error:
driver.set_context("chrome")
win = driver.find_element_by_tag_name("window")
win.send_keys(Keys.CONTROL + "-")
driver.set_context("content")
(raises NoSuchElementException)
Related questions:
stackoverflow.com/questions/28111539
stackoverflow.com/questions/60941346
stackoverflow.com/questions/67699434
stackoverflow.com/questions/56193465
stackoverflow.com/questions/32135085
...and many others.
The only way I have found that actually works is to use pyautogui, however I would rather not install additional 3rd-party libraries, & I don't believe I'll be able to run this in a headless state without a lot of hassle.
However, it seems there should be some way to do this using Selenium/geckodriver's native functionality, rather than installing additional 3rd-party packages for this purpose.
Is there a way??? The abundance of questions on this topic makes it clear that I am not the only one to have had trouble with this...
EDIT: Testing on Python 3.9, Selenium 3.141.0, geckodriver 0.29.1, Firefox 90.0, Mac OS

In Python 3.7.7, selenium 3.141.0, geckodriver 0.29.1, firefox 90.0, Ubuntu 20.04.2 LTS, I combined 2 of your items and made it work.
I could not find the window tag either, but I found body. After I got the url (and only after, otherwise I got an error), I had to do the set context to "chrome." I don't know why, but if not, as you observed, nothing happened. Then I was able to send control + or control - with the desired effect (I took two + to really see the difference, but the 110% and then 120% also shows).
driver.get(URL)#URL is a constant containing the url
driver.set_context("chrome")#needed to make keys work, must come after there is a context
win = driver.find_element_by_tag_name("body")#there is a body even if not a window
win.send_keys(Keys.CONTROL, "+")#zoom to 110%
win.send_keys(Keys.CONTROL, "+")#zoom to 120%

Related

Does it matter if used new tab or new window if I am going to use headless browser in python helium

I am using helium library for web scraping dynamic websites
I found it much faster to use tabs than using many windows yet some websites when I open them in a new tab they show some ads and I could not find a way to close them. That made me look for a lot of JS codes, which I do not understand, and most of the times they are not working when executed using helium library in python even though they work fine in the Console of Google Chrome.
However, the code should be running headless and I am doing all of this only for testing and here is my main question
Does it matter if used new tab or new window if I am going to use headless browser in python helium
is it going to be faster just like what happens when it runs normal or since it is headless it makes no difference ?
not to forget to mention that it is way easier for me to work with many windows since I won't have to use JS codes.
driver.execute_script('''$x('xpath')[0].remove();''')
driver.execute_script('''$x('xpath')[0].click();''')
$x('xpath')[0].remove();
$x('xpath')[0].click();
selenium.common.exceptions.JavascriptException: Message: javascript error: $x is not defined
they both work just fine in Google Chrome Console but for some reason, I can not execute them python helium.
I tried using to give more time using time.sleep(5) to load the page but it did not work
not to mention that I tried using the click() method from helium it gives me a LookupError()
I found a way to test it for myself it might not be accurate but the results gave me a clear winner I used the windows task manager to see the percentage of CPU usage in all the cases when running headless tabs were faster and used way less CPU than new windows

Selenium + Headless Chrome -- Cookies not saving

New to Stack Overflow posting so apologies in advance.
I am trying to use selenium + headless chrome to perform browser automation, but in initial testing noticed some odd behavior with saving cookies and other local data when comparing headless vs non headless chrome instances. For reference, my chrome version is: Version 87.0.4280.66 (Official Build) (64-bit), my chromedriver version is 87.0.4280.88. And I'm using 64-bit Centos8 to run this on.
For example, take my two pieces of code I was testing, and see the folder structure as a result in the attached image (note the difference in headless=True):
self.driver_options = Options()
self.driver_options.headless = True
self.driver_options.add_argument("--user-data-dir=/home/<user>/Projects/.headless")
self.driver_options.add_argument("--window-size=1200,1200")
self.driver = webdriver.Chrome('../bin/chromedriver',options=self.driver_options)
self.driver_options = Options()
self.driver_options.add_argument("--user-data-dir=/home/<user>/Projects/.nonheadless")
self.driver_options.add_argument("--window-size=1200,1200")
self.driver = webdriver.Chrome('../bin/chromedriver',options=self.driver_options)
Here's a picture comparing directory structure of headless (left) and non-headless (right)
I read that this may have something to do with headless chrome instances using a different data directory, so maybe some of the files are 'missing' due to that (in another location) - but the biggest issue is that the [user-dir]/Default/Cookies file is populated in the non-headless version, but unpopulated in the headless version. I've also tried to remedy it by adding a "remote-debugging-port" option, but still got the same outcome.
I want to run a few different headless threads, where cookies are important for long running jobs. Has anyone seen anything like this, or know why I am experiencing this behavior? Is it to be expected?
Thanks all

Selenium ActionChains simulated mouse control with Python is 10x slower than simulated keystrokes - why is this, and is there a better way?

I'm building a Selenium ActionChain via Python to hold and execute keyboard and mouse input. When the ActionChain only contains several keystrokes (through action.key_down() or action.key_up()), it executes in well under 0.01 s. As soon as I add a single cursor movement (using action.move_by_offset()) the execution time shoots up to 0.3-0.4 s.
First off, what's the technical difference that makes the mouse input so much more expensive?
Is there any better Selenium-based alternative, or should I be using a different tool for realtime browser input?
(For context, I'm using Selenium to run a reinforcement learning model on HTML5 multiplayer web games, so I need to execute actions as quickly as possible or my bot's reaction time suffers. I'm using the Firefox webdriver - I also tried Chrome, but found the geckodriver to be about twice as fast for mouse input. Ideally, I need to get all of my input execution to run in about 0.01 s so it doesn't slow down my model.)
If anyone is still looking for a fix here is what I did:
from selenium.webdriver.common.action_chains import ActionChains
actions = ActionChains(driver, duration=10) # duration in milliseconds
actions.move_to_element_with_offset(website_element, x, y).perform()
I found this out from looking a bit in the source and seeing a duration argument that was left on the default of 250 ms. Does anyone know why they do this?
I dont know the answers to your other questions though
I still can't answer why the issue exists beyond orde's note above, but I did find that Selenium doesn't seem like the best tool for this, and was able to (somewhat crudely) work around it using additional libraries.
For anyone else with a similar need:
I ended up using D3DShot for video (much faster frame grab than Selenium) and PyAutoGUI for much faster mouse control (closer to 1 ms). I still utilize Selenium, but only to navigate to the site, log in, and put the game window in full screen.
Unfortunately this setup effectively prevents multiple bots from running on the same machine (you might be able to hack something together with one bot per display, but that would get pretty messy.)

Selenium ActionChains working on some PCs, not others

I'm developing a data scraping script using Selenium and Python and I've got the following line of code which works on my Ubuntu PC, my wife's Windows PC but not my colleague's Windows PC.
ActionChains(driver).context_click(inputElement).send_keys(Keys.ARROW_DOWN).click().perform()
We're in the UK and he is in Canada is the only difference I know of.
EDIT
What I've realised is happening, but I do not know how to resolve, is the Keys.ARROW_DOWN is being performed on the webpage and not on the context_click element. Any thoughts? Is this a Chrome issue?
That might be a timing issue related to the quality of the network connection to the target site.
I'd strengthen it by introducing an Explicit Wait for the inputElement, use the WebDriverWait with element_to_be_clickable Expected Condition before starting the action chain.
You may also add a "scroll into view" of the element to tackle potential browser/resolution/etc specific layout issues:
driver.execute_script("arguments[0].scrollIntoView();", inputElement)
Solution:
I rewrote using Firefox instead of Chrome and it is working fine.

Automating Flash Program with Python using Pywinauto

I am trying to send a couple basic text commands to a flash program running in Firefox on Windows 7, but I am unable to get pywinauto working for me.
Right now, I have just been able to accomplish the very basic task of connecting to Firefox plugin-container by directing it to the path using the following code:
from pywinauto import application
app = application.Application()
app.connect_(path = r"c:\Program Files (x86)\Mozilla Firefox\plugin-container.exe")
The next step seems to be something to the effect of:
app.plugin-container.Edit.TypeKeys('Text')
However, I can't reference the plugin-container window using '.plugin-container', or any combination of those words. I have tried adding a title variable to the connect_() function and I have tried everything I can think of to find out how to type the command.
The example I am basing this off of is the notepad sample:
from pywinauto import application
app.start_(ur"notepad.exe")
app.Notepad.Edit.TypeKeys(u"{END}{ENTER}SendText d\xf6\xe9s "
u"s\xfcpp\xf4rt \xe0cce\xf1ted characters!!!", with_spaces = True)
It doesn't matter to me if I use pywinauto or Firefox. If it is any easier to do this using a different module or Internet Explorer, I'm on board for whatever accomplishes the task. I am using Python version 2.7.2 and would prefer it over any version changes.
Any help at all is appreciated. I am pretty lost in all this.
As the author of pywinauto - I think you are going to have a hard time. pywinauto only really helps with standard windows controls, and I don't think that flash controls are implemented as standard windows controls (Buttons, Edit boxes, etc).
OFf the top of my head - I would think Sikuli may be a better starting point (http://sikuli.org/).
Another option may be 'http://code.google.com/p/flash-selenium/' - I just googled for "automating flash input" - and it turned up in one of the first articles I clicked.
Thanks for trying pywinauto - I just don't think it is best suited for Flash automation.

Categories