-
Notifications
You must be signed in to change notification settings - Fork 0
selenium
You can:
- execute .js commands, ...
- interact with websites,
- ...
Selenium is availible in lots of different programming languages - not only python.
pip3 install selenium
Then you normally need download a driver for your desired browser:
URL: http://www.seleniumhq.org/download/ refer to Third Party Drivers, Bindings, and Plugins
URL: https://www.selenium.dev/downloads/ go to Platforms Supported by Selenium
Direct links:
- Chromium: https://sites.google.com/chromium.org/driver/
- Firefox/Gecko: https://github.com/mozilla/geckodriver/releases
Then copy the files to the right place & adapt permissions.
sudo mv geckodriver /usr/bin/
chmod a+x /usr/bin/geckodriver
Just add your executable of the Gecko driver to your Path
variables. For example:
# local (per `cmd.exe` session)
set PATH=%PATH%;C:\Users\usr\AppData\Local\Programs\geckoDriver
# global
setx PATH C:\Users\usr\AppData\Local\Programs\geckoDriver /m
# Or just add path via GUI
If path is not set correctly you probably get an error message like Exception AttributeError: "'Service' object has no attribute 'process'" in <bound method Service.__del__ of <selenium.webdriver.firefox.service.Service object at 0x1006890d0>> ignored
Now we are ready to go! :D
import time
from selenium import webdriver
from pyvirtualdisplay import Display # Optional: use virtual display for use in headless env (servers without X)
display = Display(visible=0, size=(800, 600)) # Not necessarily needed
display.start() # Not necessarily needed
browser= webdriver.Chrome() # For Firefox: browser = webdriver.Firefox()
browser.get("https://github.com/TeamFlowerPower") # Access page
wait = 5
print(f"Waiting for {wait} seconds that page is completely loaded...")
time.sleep(wait)
print(browser.current_url) # Print URL
print(browser.page_source.encode('utf-8'))
contentXPattern = r'//*[@id="MainPart_lbUsersInLineAheadOfYou"]'
result = None
try:
someVarTmp = browser.find_element_by_xpath(contentXPattern) # Raises an NoSuchElementException when pattern not found
someVar = someVarTmp.text # Convert to text
print(f"Users ahead of me: {someVar}")
except Exception as ex:
exName = type(ex).__name__ # Get exception name for printing
print(f"XPath not found ({exName})")
#browser.quit()
result = None
else:
result = {someVar: browser}
browser.quit()
display.stop() # Not necessarily needed
Note: quit()
may raise a warning/exception in Firefox; there is also close()
where this message does not show up using Firefox but it does not close the window either.
browser.execute_script("document.getElementById('email').setAttribute('value', 'recipient@gmail.com')");
TODO
Most in modern Selenium with JavaScript is based on Promises: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises
Here also arrow-functions become handy.
// Traditional anonymous function
function (name){
return `hello ${name}`;
}
# becomes:
(name) => {
return `hello ${name}`;
}
namedArrowFunction = (name) => `hello ${name}`; // Only omit the `return` for one-line functions (no curly braces)
About template literals -> `${}`
Allows sequentiality of promises:
A common need is to execute two or more asynchronous operations back to back, where each subsequent operation starts when the previous operation succeeds, with the result from the previous step. We accomplish this by creating a promise chain.
Here's the magic: the then() function returns a new promise, different from the original
(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#chaining)
XPath, CSS, ...
# XPath
//div[starts-with(@class,'class-name-fragment-start')]
//*[contains(@class,'class-name-fragment')]
//div[ends-with(@class,'class-name-fragment-start')]
# `*`: any element
# CSS
div[class^='class-name-fragment-startswith']
div[class*='class-name-fragment-contains']
div[class$='class-name-fragment-endswith']
The Attribute is role
(with the name button
) in this example:
# XPath
//div[@role = 'button']
# CSS
div[role = 'button']
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License *.
Code (snippets) are licensed under a MIT License *.
* Unless stated otherwise