I have a bookmarklet that executes successfully from the browser:
javascript:!function(a){var b=document.createElement("textarea"),c=document.getSelection();b.textContent= a,document.body.appendChild(b),c.removeAllRanges(),b.select(),document.execCommand("copy"),c.removeAllRanges(),document.body.removeChild(b);}(<text here>);
When I try to execute this through the Selenium webdriver using Python it is returning None. Any thoughts on how to get this to copy the text to the clipboard like the bookmarklet? Full code is below:
from selenium import webdriver
chromeOptions = webdriver.ChromeOptions()
chromeOptions.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=chromeOptions, desired_capabilities=chromeOptions.to_capabilities())
driver.implicitly_wait(5)
driver.get("websitehere")
js = """javascript:!function(a){var b=document.createElement("textarea"),c=document.getSelection();b.textContent= a,document.body.appendChild(b),c.removeAllRanges(),b.select(),document.execCommand("copy"),c.removeAllRanges(),document.body.removeChild(b);}(<texthere>);
"""
print(driver.execute_script(js))
After some reading online it looks this type of work flow is blocked due to security concerns. I was seeing this error in the console chrome document.execCommand(‘cut’/‘copy’) was denied because it was not called from inside a short running user-generated event handler.
Note that below did not work on Firefox only Chrome may start failing on Chrome in the next couple versions.
from selenium import webdriver
import time
import pyperclip
import pyautogui
driver = webdriver.Chrome(executable_path=r'C:\\Path\\To\\chromedriver.exe')
driver.get("https://www.google.com")
time.sleep(2)
pyautogui.hotkey('ctrl', 'shift', 'j')
time.sleep(2)
js2 = """
var testCopy = function(a) {
var b=document.createElement("textarea"), c=document.getSelection();
b.textContent = a,
document.body.appendChild(b)
c.removeAllRanges()
b.setAttribute("id", "testid")
b.select()
document.execCommand("copy")
console.log('copy success', document.execCommand('copy'));
c.removeAllRanges();
}
testCopy("ThisText")
"""
driver.execute_script(js2)
time.sleep(1)
a = pyperclip.paste()
print(a)
Related
I am trying to learn Selenium in Python and I have faced a problem which stopped me from processing.
As you might know, previous versions of Selenium have different syntax comparing the latest one, and I have tried everything to fill the form with my code but nothing happens. I am trying to find XPATH element from [https://demo.seleniumeasy.com/basic-first-form-demo.html] but whatever I do, I cannot type my message into the message field.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service as ChromeService
import time
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
service = ChromeService(executable_path="C:/Users/SnappFood/.cache/selenium/chromedriver/win32/110.0.5481.77/chromedriver.exe")
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://demo.seleniumeasy.com/basic-first-form-demo.html")
time.sleep(1000)
message_field = driver.find_element(By.XPATH,'//*[#id="user-message"]')
message_field.send_keys("Hello World")
show_message_button = driver.find_element(By.XPATH,'//*[#id="get-input"]/button')
show_message_button.click()
By this code, I expect to fill the message field in the form and click the "SHOW MESSAGE" button to print my typed text, but what happens is that my code only opens a new Chrome webpage with empty field.
I have to mention that I don't get any errors by PyCharm and the code runs with no errors.
I would really appreciate if you help me through this to understand what I am doing wrong.
You need to wait for the page loads correctly.
For this, the best approach is using WebDriverWait:
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://demo.seleniumeasy.com/basic-first-form-demo.html")
# Wait for the page to load
wait = WebDriverWait(driver, 10)
wait.until(lambda driver: driver.find_element(By.XPATH, '//*[#id="user-message"]'))
message_field = driver.find_element(By.XPATH,'//*[#id="user-message"]')
message_field.send_keys("Hello World")
show_message_button = driver.find_element(By.XPATH,'//*[#id="get-input"]/button')
show_message_button.click()
Tested, it works fine.
Also you can use time.sleep() to wait the load if you know the loading times:
import time
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://demo.seleniumeasy.com/basic-first-form-demo.html")
time.sleep(5)
message_field = driver.find_element(By.XPATH,'//*[#id="user-message"]')
message_field.send_keys("Hello World")
time.sleep(5)
show_message_button = driver.find_element(By.XPATH,'//*[#id="get-input"]/button')
show_message_button.click()
time.sleep(5)
with this xpath you have two elements //*[#id="user-message"] . you need to make it unique. Try below xpath this will work as expected.
message_field = driver.find_element(By.XPATH,'//input[#id="user-message"]')
browser snapshot:
I am trying to take a screenshot of a given website without scrolling down.
I'm using Selenium WebDriver for automation and I'm using Chromedriver.
Problem 1: I have noticed that when my driver runs and opens the chrome browser, it opens the browser with a small size. I tried the following but couldn't know how to set it to maximum and not take the scroll wheel on the right in the screenshot (see image below).
Problem 2: I want to block any chatbots or cookies so that I can take a clean screenshot (see image below).
The following is what I have tried.
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = webdriver.ChromeOptions()
options.headless = False # don't know sure what this does!
options.add_argument("--window-size=1700,1000")
options.add_argument("disable-popup-blocking")
options.add_experimental_option("prefs", {
"profile.default_content_setting_values.cookies": 2
}
)
driver = webdriver.Chrome(options=options)
URL = 'https://apploi.com/'
driver.get(URL)
sleep(1)
driver.get_screenshot_as_file('apploi.png')
driver.quit()
print("end...")
Desired screenshot output is to look like this:
Here's a SeleniumBase pytest test that will do all that:
from seleniumbase import BaseCase
class MyTestClass(BaseCase):
def test_screenshot(self):
self.open("https://apploi.com/")
self.remove_element("[data-nosnippet]")
self.save_screenshot("my_screenshot.png")
Save that to a file, and run it with pytest after installing seleniumbase.
import By
from selenium.webdriver.common.by import By
options.add_argument("--window-size=1920x1080")
add this to maximize your screen
options.add_argument("--start-maximized")
to remove cookie permission
cookie = driver.find_element(By.ID,'hs-eu-cookie-confirmation')
driver.execute_script("""
var element = arguments[0];
element.parentNode.removeChild(element);
""", cookie)
and lastly, add this to take screenshot
driver.save_screenshot("screenshot.png")
by the way you can remove this line. by default headless is false.
options.headless = False # don't know sure what this does!
you can't run headless mode on that website
first link was just a selenium script for access to youtube
from selenium import webdriver
PATH = r"C:\Users\hp\Desktop\prog\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("https://youtube.com")
this python program works perfectly fine
but when i try the same thing with a cloudflare protected website it gets stuck in the wait page
i did some research and found an undetected chrome driver to use but i keep getting errors like :
RuntimeError, the libraris are all perfectly installed
did more research and found a youtube video that i could follow but Im still getting errors
here is the second code
import selenium
import undetected_chromedriver.v2 as uc
import time
options = uc.ChromeOptions()
py = "24.172.82.94:53281"
options.add_argument('--proxy-server=%s' % py)
driver = uc.Chrome(options=options)
driver.get("https://ifconfig.me/")
time.sleep(4)
the error i get : AttributeError: 'ChromeOptions' object has no attribute 'add'
For something related to processes, wich i connot fully understand, you have to the lines driver = uc.Chrome() and driver.get('https://namecheap.com') in the if __name__ == '__main__':.
Also the link has to have the https:// or http:// for it to work
Here's my working code:
import undetected_chromedriver as uc # the .v2 is not necessary in the last version of undetected_chromedriver
import time
def main():
time.sleep(4)
#continue your code here
if __name__ == '__main__':
driver = uc.Chrome()
driver.get('https://namecheap.com')
main()
I am trying to get logs from Chrome's console using Selenium with Python and a little bit lost because it is my first experience with it.
In general, the code works and prints logs, but I need to see some specific events, that I normally see by typing a command _newsb.getEv.getBuffer() (it is an imaginary command, I am using something similar). With Selenium, I am trying to input it like this driver.execute_script("_newsb.getEv.getBuffer()"), but I don't see events.
Here is the code:
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
dc = DesiredCapabilities.CHROME
dc['goog:loggingPrefs'] = { 'browser':'ALL' }
driver = webdriver.Chrome(desired_capabilities=dc, service_args=["--verbose", "--log-path=D:\\qc1.log"])
driver.implicitly_wait(30)
driver.get('https://www.somewebsite.com/')
page = driver.find_element_by_tag_name("html")
driver.execute_script("window.scrollTo(0, 400)")
time.sleep(3)
driver.execute_script("_newsb.getEv.getBuffer()")
time.sleep(3)
driver.execute_script("window.scrollTo(0, window.scrollY + 400)")
time.sleep(3)
driver.execute_script("window.scrollTo(0, window.scrollY + 400)")
time.sleep(1)
for entry in driver.get_log('browser'):
print(entry)
driver.quit()
Could someone please point out what I am doing wrong and how do you input in console with Selenium and Python? Any advice is appreciated.
Also, how to see all logs, including info and Verbose, not just errors?
options.set_capability("goog:loggingPrefs", { # old: loggingPrefs
"browser": "ALL"})
driver = webdriver.Chrome(
options=options
)
# returns a list of all events
driver.execute_script("window.open('');")
driver.switch_to.window(driver.window_handles[1])
driver.get('http://www.google.com')
driver.execute_script("console.error('This is error')")
driver.execute_script("console.info('This is info')")
driver.execute_script("console.log('This is log')")
logs = driver.get_log("browser")
print(logs)
sleep(100000)
This prints all the 3 types of logs i am not sure if you are looking for this
I want to keep Firefox Login status when using Selenium WebDriver (geckodriver). I used below python code:
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
import time
try:
fp = webdriver.FirefoxProfile('C:/Users/admin/AppData/Roaming/Mozilla/Firefox/Profiles/mow8ff69.selenium')
options = Options()
options.headless = False
browser = webdriver.Firefox(fp, options=options)
browser.get('https://stackoverflow.com/users/login');
time.sleep(2)
txt_username = browser.find_element_by_id('email')
txt_username.clear()
txt_username.send_keys('***#gmail.com') #replace with your own username
time.sleep(1)
txt_password = browser.find_element_by_id('password')
txt_password.clear()
txt_password.send_keys('*****') #replace with your own password
time.sleep(1)
txt_password.submit()
time.sleep(10)
except Exception as ex:
print('Error: {0}'.format(ex))
finally:
browser.quit()
As shown above, I have been using a User Profile created by "Firefox -p". However, after running above code, when I reopen Firefox using that profile and then go to stackoverflow.com, I'm still not logged in.
So it looks like that Selinum WebDriver actually runs firefox in a "sandbox" which cannot write to the User Profile at all? I know that ChromeDriver has a "--no-sandbox" option but it doesn't seem to be available in geckodriver? Is there any workaround?
I cannot switch to ChromeDriver because there is another bug with it: the "--headless" option actually conflicts with "--user-data-dir" option whereas I really need both.