so I'm fairly new to python but I start to understand how things work together, however for this problem I didn't find any solution.
So my problem is I'm making a simple bot with python that can open Youtube and search for specific keywords, Now I have tried the send.keys method and it won't work because I want to use special characters that ChromeWebDriver just can't send due to chromedriver only supports characters in the bmp Problem!
So then I explored my options 1 using GeckoDriver Firefox instead and yeah it worked! however, I couldn't make Firefox undetected as a bot!
option 2 is using the execute_script method with ChromeWebDriver it did work at first with Google search, But then I wanted to use it for Youtube and nothing happens.
I run my script browser works youtube page is loaded but nothing happens the script completes the 20s sleep and exists normally but no input has been made in the search bar or any error in my console just nothing!
maybe the element is not loaded? but I put 20sec sleep after each line of code to make sure the page have enough time to load properly I tried to use Find_by_id | xPath | class_name still nothing
I tried to check if the element is there before executing the input text line and still nothing
Also, I have tried to .click the element before doing text input the search bar is highlighted the click worked but still no text and nothing.
As for the characters I'm trying to input into the search bar are like this: 𝕊 𝕄
which can't be sent by the send.key method
My code:
import undetected_chromedriver.v2 as uc
from time import sleep
import jdk
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
if __name__ == '__main__':
driver = uc.Chrome()
driver.get('https://youtube.com')
sleep(20)
driver.execute_script("document.getElementById('search').checked = true;")
print('Searching for Element')
sleep(20)
Elem_nt = driver.find_element(By.XPATH, "/html/body/ytd-app/div/div/ytd-masthead/div[3]/div[2]/ytd-searchbox/form")
print('Finding Element Now...')
sleep(20)
driver.find_element(By.XPATH, "/html/body/ytd-app/div/div/ytd-masthead/div[3]/div[2]/ytd-searchbox/form").click()
print('Clickling Element Now')
sleep(20)
driver.execute_script("arguments[0].value = 'vid_title';", Elem_nt)
print('input Text Now')
sleep(20)
Any help would be appreciated, also excuse the terms that I use to explain as I'm new to this I just want to explain everything.
Try this one
import pyperclip
from selenium.webdriver.common.keys import Keys
pyperclip.copy(your_text)
element = driver.find_element(By.CLASS_NAME,"your_class_name")
element.send_keys(Keys.CONTROL + "V")
I'm new to coding in python and I'm wondering if some one can explain why this code works on the second try but not on the first?
I was just trying to open a browser that was not the default one.
first try --> did not work
import webbrowser
url='https://www.mozilla.org'
webbrowser.register('firefox', None)
webbrowser.BackgroundBrowser("C:\\Program Files\\Mozilla Firefox\\firefox.exe")
webbrowser.get('firefox').open(url)
webbrowser.Error: could not locate runnable browser
Process finished with exit code 1
second try --> works
import webbrowser
url='https://www.mozilla.org'
webbrowser.register('firefox', None, webbrowser.BackgroundBrowser("C:\\Program Files\\Mozilla Firefox\\firefox.exe"))
webbrowser.get('firefox').open(url)
Process finished with exit code 0
Like you can see here, register tells Python where the webbrowser with the name "firefox" can be found. You have to pass an instance (BackgroundBrowser) or a constructor. In the first code snippet you pass None as the constructor, which is not a valid browser class, it can thus not find/create the browser and cannot register it. In the second snippet you pass your BackgroundBrowser instance and thus it can register this valid browser as "firefox" and you can run it later.
The 5th line (webbrowser.BackgroundBrowser...) in the first snippet does basically nothing, you are supposed to give that as an argument to register like you do in the second snippet.
I've written a script in Python using Selenium to log in to Instagram and then search for some hashtag, as in #NewYorkbarbers, and get the link of that hashtag. My script can successfully log in, click on the Not Now button if Turn on Notifications box shows up, and then put that hashtag in the search box, but I can't make my script initiate that search to produce result against that hashtag.
I've tried so far:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class InstagramScraper:
login_url = 'https://www.instagram.com/accounts/login/?source=auth_switcher'
def __init__(self,username,password):
self.driver = webdriver.Chrome()
self.wait = WebDriverWait(self.driver,10)
self.login(username,password)
def login(self,username,password):
self.driver.get(self.login_url)
self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,'input[name="username"]'))).send_keys(username)
self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,'input[name="password"]'))).send_keys(password)
self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,'button[type="submit"]'))).click()
try:
self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,'button.HoLwm'))).click()
except Exception:pass
def use_hashtag(self):
self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,'input[placeholder="Search"]'))).send_keys("#NewYorkbarbers",Keys.ENTER)
if __name__ == '__main__':
scraper = InstagramScraper('username','password')
scraper.use_hashtag()
How can I use return within login() method as any ideal method should have return statement within it?
How can I produce the result of that hashtag search?
General Idea of having return statement is to go back.
When you have return in a statement it goes back to the place from where it is got called.
when u write return value it means go back and take this value.
If no return statement is given it means return None
You are using Enter key to initiate the search, but if you go and open Instagram in the browser you will know that even manually that is not possible.
Instagram does not initiate the search simply on a single key hit of enter, when you press enter for the first time it will focus on the very first search suggestion which takes a little bit of time to load (which is not guaranteed to be the #tag that you type so it is better to also check text and the click on particular #tag) and when you press the enter second time it will initiate the search for hashtag that is right now focused.
Even this is not enough, in fact, you need to wait for the suggestion dropdown of the search box to open and then find the desired #tag from the suggested item and press enter.
Basically, the script is too fast to give time for search suggestions to appear (Even manually you can hit Enter two times faster then dropdown to appear and search won't be initiated.) and also it requires two times hit of Enter, first will focus the very first suggestion and second will initiate the search.
In python, not all functions need to return something, and it's not even a convention to have all functions end with a return statement (Unlike other languages such as C). In fact, according to this question, it would be best practice not to have a return statement. But a simple return at the end of the function will be the best option if you really insist on having an explicit return statement.
As for your other problem, a new div appears when the search suggestions have loaded, so you have to wait for that div, then send enter twice.
Here is the new use_hashtag method: (sorry for using xpath and not css selector, but I'm not familiar with css and the chrome developer tools kept giving things dependent on class names):
def use_hashtag(self):
search_input = self.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR,'input[placeholder="Search"]')))
search_input.send_keys("#NewYorkbarbers")
self.wait.until(EC.visibility_of_element_located((By.XPATH, '//*[#id="react-root"]/section/nav/div[2]/div/div/div[2]/div[2]/div[2]')))
search_input.send_keys(Keys.ENTER, Keys.ENTER)
How to upload a picture on a web application with the selenium testing tool? I am using python.
I tried many things, but nothing worked.
What I'm doing is this (make sure drv is an instance of webdriver):
drv.find_element_by_id("IdOfInputTypeFile").send_keys(os.getcwd()+"/image.png")
and then find your submit button and click it.
A very easy way to control components like windows file selector (or just your OS in general) is by using pyautogui. You can install pyautogui through pip
import pyautogui
... # set the webdriver etc.
...
...
element_present = EC.presence_of_element_located((By.XPATH, "//button[#title='Open file selector']")) # Example xpath
WebDriverWait(self.driver, 10).until(element_present).click() # This opens the windows file selector
pyautogui.write('C:/path_to_file')
pyautogui.press('enter')
I am using fine-uploader, running selenium tests with pytest and this worked for me:
elm = driver.find_element_by_xpath("//input[#type='file']")
elm.send_keys(os.getcwd() + "/tests/sample_files/Figure1.tif")
No form submission or Enter key is needed in my case.
I added an answer for anyone looking to use deal with the annoying msofiledialogs. This is working off of saravanan's proposed solution, but more fleshed out for Python.
I had a similar problem with a script I'm working on for a company on the side. I'm attempting to upload documents for a company's clients, but due to the way their site worked, I could not utilize send_keys to directly send the path, so I had to rely on msofiledialog.
You only need to install AutoIt
https://pypi.python.org/pypi/PyAutoIt/0.3 or just "pip install -U pyautoit" through the cmd screen
type "import autoit" on your script page
Type the following before the file dialog pops up in your script:
autoit.win_active("Open")
autoit.control_send("Open","Edit1",r"C:\Users\uu\Desktop\TestUpload.txt")
autoit.control_send("Open","Edit1","{ENTER}")
It will look for the open file dialog window and fill it out and press enter.
"Open" is the title of my file dialog screen. Put the title of yours in place of "Open". There are more creative ways to utilize AutoIt's functions, but this is an easy, straightforward way for beginners.
Edit: DO NOT. DO NOT use control_send on most things if you can avoid it. It has a well-known issue of sending erroneous text. In my case, the colon in my file path was being turned into a semi colon. If you need to send input keys, it should be fine, however if you need to send text, use control_set_text. It has the same syntax.
autoit.control_set_text("Open","Edit1",r"C:\Users\uu\Desktop\TestUpload.txt")
All these approach wont work with modern image uploaders in olx !!!
Alternative approach (only for windows )
1. Automation of windows can be done using Autoit
2. Install Autoit and SciTe Script editor
3. Autoit code :(imageupload.au3)
WinActivate("File Upload"); for chrome use "open" that is the name of the window that pops
send("D:\images\image1.png"); path of the file
Send("{ENTER}")
4. compile it to get an .exe file(imageupload.exe)
5. Now from python call the .exe file like
import os
import os.system('C:\images\imageupload.exe') #path of the .exe file
Upload input control opens a native dialog (it is done by browser) so clicking on the control or browse button via Selenium will just pop the dialog and the test will hang.
The workaround is to set the value of the upload input via JavaScript (in Java it is done via JavascriptExecutor) and then submit the form.
See this question for sample in C#, I am sure there's also a way to call JavaScript in Python but I never used Selenium Python bindings
Here is the code that i used:
Imagepath = "C:\User\Desktop\image.png"
driver.find_element_by_xpath('//html/body/input').send_keys(Imagepath)
driver.find_element_by_xpath('//html/body/button').click()
I accept the Answer by karloskar. Note It is not working for FireFox (59). And it is works with Chrome Driver only.
import win32com.client
shell = win32com.client.Dispatch("WScript.Shell")
shell.Sendkeys("C:\text.txt")
shell.Sendkeys("~")
Will resolve the issue
You can easily add this one line of code to solve the problem:
driver.find_element_by_xpath("your fullpath").send_keys("C://1.png(your file root")
But pay attention, sometimes maybe you put a wrong xpath in first field. follow below steps for reach to rightful xpath:
open the inspect and click exactly on the box which you want to
upload the file.
right click on the html code and select xpath full address from copy
sub menu.
paste the root in xpath field in the code.
full code to achieve file upload using autoit tool.
u can just copy paste this and u can run, it will work since it is a acti-time demo.
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time
import os
def fileUploading():
driver = webdriver.Firefox()
driver.implicitly_wait(20)
wait = WebDriverWait(driver, 10)
driver.get("https://demo.actitime.com/login.do");
driver.find_element(By.ID,"username").send_keys("admin")
driver.find_element(By.NAME, "pwd").send_keys("manager")
driver.find_element(By.XPATH, "//div[.='Login ']").click()
wait.until(ec.element_to_be_clickable((By.XPATH, "(//div[#class='popup_menu_icon'])[3]")))
driver.find_element(By.XPATH, "(//div[#class='popup_menu_icon'])[3]").click()
wait.until(ec.element_to_be_clickable((By.XPATH, "//a[contains(text(),'Contact actiTIME Support')]")))
driver.find_element(By.XPATH, "//a[contains(text(),'Contact actiTIME Support')]").click()
wait.until(ec.element_to_be_clickable((By.XPATH,"//div[#class='dz-default dz-message']")))
driver.find_element(By.XPATH,"//div[#class='dz-default dz-message']").click()
os.system("C:\\Users\\mallikar\\Desktop\\screenUpload.exe")
time.sleep(2000)
fileUploading()
below is the content of autoit code:
WinWaitActive("File Upload")
Send("D:\SoftwareTestingMaterial\UploadFile.txt")
Send("{ENTER}")
download autoIt and autoIt SCITE editor tool.
once done install autoit and the open the scite editor and paste the above code and save it with .au3 extension and once saved, right click on the file and select complile script(x64), now .exe file is created.
now use the below code:
os.system("C:\\Users\\mallikar\\Desktop\\screenUpload.exe")
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get("http://www.example.org")
def upload_file():
upload_file = driver.find_element_by_id("paste here id of file which
is
enter code here`shown in html code...")
upload_file.send_keys("copy the path of file from your pc with name and
paste here...")
if toast message is disappeared within seconds you can use Chropath extension in chrome to find its xpath
This is a pure python code.
Instead of using control_send, use control_set_text to resolve inconsistencies present in the string sent to the window. See this link for reference: https://www.autoitscript.com/forum/topic/85929-incorrect-string-being-sent-via-controlsend/
import autoit
autoit.win_wait_active("Open")
autoit.control_set_text("Open", "Edit1", imgPath)
autoit.send("{ENTER}")
Use PyAutoGui if sendkeys function is not working on buttons.
sample code:
import pyautogui
driver.find_element_by_xpath("Enter Xpath of File upload button").click()
time.sleep(4) #waiting for window popup to open
pyautogui.write(r"C:\Users\AmarKumar\FilesForUploading\image.jpg") #path of File
pyautogui.press('enter')
I have used below script format to upload the images. This may help you.
Imagepath=os.path.abspath('.\\folder1\\subfolder2\file1.jpg')
driver.find_element_by_id("Id of the element").clear()
driver.find_element_by_id("Id of the element").send_keys(Imagepath)
if you do not have ID of the object ,then you can use xpath or css selector accordingly.
Using splinter :
browser.attach_file('file_chooser_id',fully_qualified_file_path)
If you are using service you will get an exception
service = Service('driver_path')
service.start()
driver = webdriver.Remote(service.service_url)
choose_image = driver.find_element(By.ID, 'id')
choose_image.send_keys(os.getcwd()+'/image.jpg')
Exception :
selenium.common.exceptions.WebDriverException: Message: unknown command: unknown command: session/$sessionId/se/file
Working code (suggestion - use id of the element instead of other)
driver=webdriver.Chrome(executable_path=driver_path)
choose_image=driver.find_element(By.ID, 'id')
choose_image.send_keys(os.path.join(os.getcwd(), 'image.jpg'))
In case you want to upload multiple pictures, you can alter the single image answer as follows:
images = ["/path/to/image1.png", "/path/to/image2.png","/path/to/image3.png"]
drv.find_element_by_id("IdOfInputTypeFile").send_keys("\n".join(images))
Note that the input form should have the multiple attribute set to True.
I post a solution that i consider best. it is a modification on solution by #sherlock (see my comment on that post)
import autoit
autoit.win_wait_active("Open")
autoit.control_set_text("Open", "Edit1", imgPath)
autoit.control_click("Open", "Button1")
Install these three
sudo apt-get install python3-tk python3-dev
pip install tk
pip install PyAutoGUI
use these two line of code.
pyautogui.write('/home/image.jpg')
pyautogui.press('enter')
There is this website my teacher makes us use to improve our typing skills. Our assignment is due next month and I am too lazy and want to make a program using selenium, a python module. Everything is working according to plan accept one thing, how do I type on the browser. You don't type in a text box. Here is my code:
from selenium import webdriver
driver = webdriver.Chrome('/Users/iyadmajid/Desktop/chromedriver')
driver.set_page_load_timeout(30)
driver.get('https://www.typing.com/student/login')
driver.implicitly_wait(20)
driver.find_element_by_id('username').send_keys('the_username')
driver.find_element_by_name('password').send_keys('the_password')
driver.find_element_by_class_name('submit-login').click()
driver.find_element_by_xpath("//a[#href='/student/lessons/380/numeric-
keypad']").click()
driver.find_element_by_xpath("//a[#class='button begin-button tooltip-
trigger']").click()
This is what the screen looks like after the code finishes executing: the website. I tried using send_keys('6') but that doesn't work. Here is what website code looks like: the website code. Again, if there is a way to type keys on the browser directly, please let me now.
There is, try the PyAutoGui module. It can be installed with pip and can press keys. An example that presses the y key:
import pyautogui
pyautogui.press('y')
Like this:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.firefox()
driver.get("https://www.typing.com/student/login")
select element by id:
inputElement = driver.find_element_by_id("a1")
inputElement.send_keys('1')
Now you can simulate hitting ENTER:
inputElement.send_keys(Keys.ENTER)
or if it is a form you can submit:
inputElement.submit()