copying text selenium using .text() - python

I need to scrape some text from a table, using selenium. I'm a complete novice, but thanks to Stack overflow, I was able to get to get pretty far. Now I am getting an error when using text() to copy text. Here are my codes.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium import webdriver
driver = webdriver.Chrome('C:/Users/User/Downloads/chromedriver')
url = "https://aca.tampagov.net/citizenaccess/Default.aspx#"
driver.get(url)
# The website I need to check
# Click "search" at the top menu
driver.find_element_by_xpath('//*[#id="main_menu"]/ul/li[2]/a').click()
# Click "building permits" in the menu that follows below
driver.find_element_by_xpath('//[#id="main_menu"]/ul/li[2]/ul/li[1]/a').click()
#change iframes
driver.switch_to.frame("ACAFrame")
# When changing iframes, I was recommended that I should use this,
# WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//*[#id='ACAFrame']")))
# but I'm now having troubles running this line so I changed it to the line like above
Now you can find that there's a table below. I want to copy text using a code such as:
driver.find_element_by_xpath('//tbody/tr[3]/td[4]').text()
But I get, instead:
Traceback (most recent call last):
File "<ipython-input-117-2a4c7f9321b5>", line 1, in <module>
driver.find_element_by_xpath('//tbody/tr[3]/td[4]').text()
TypeError: 'str' object is not callable
What am I doing wrong here?

Use
driver.find_element_by_xpath('//tbody/tr[3]/td[4]').text
instead of
driver.find_element_by_xpath('//tbody/tr[3]/td[4]').text()
The statement driver.find_element_by_xpath('//tbody/tr[3]/td[4]').text returns a string, so you don't have to add the parenthesis at the end. If you add the parenthesis, then syntax means you are calling it, but you can only call callable objects, such as functions. Thus, the error.

Related

Selenium Python: TypeError: 'str' object is not callable whenever trying to print an element / element text

I'm trying to scrape a telegram channel by going to the last message and print the text inside it / store it in a variable to use it later.
Code trials:
from cgitb import text
from http import server
from re import search
import selenium
import time
import sys
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
PATH = "/usr/local/bin/chromedriver"
driver = webdriver.Chrome(PATH)
driver.get("https://t.me/s/klfjezlkjfzlek")
test = driver.find_element(By.XPATH("//html//body//main//div//section//div//div//div//div[#class='tgme_widget_message_text js-message_text before_footer'][last()]"))
source_code = test.text
print(source_code)
I get the following error :
Traceback (most recent call last):
File "/Users/usr/Desktop/tg.py", line 16, in <module>
text=driver.find_element(By.XPATH("//html//body//main//div//section//div//div//div//div[#class='tgme_widget_message_text js-message_text before_footer'][last()]"))
TypeError: 'str' object is not callable
That would be because By.XPATH is actually a string. Here's some further reading from Selenium's docs.
You may use find_element_by_xpath:
test = driver.find_element_by_xpath("//html//body//main//div//section//div//div//div//div[#class='tgme_widget_message_text js-message_text before_footer'][last()]")
or driver.find_element(By.XPATH, "..."):
test = driver.find_element(By.XPATH, "//html//body//main//div//section//div//div//div//div[#class='tgme_widget_message_text js-message_text before_footer'][last()]")
Hope that helps!
Um in your code you have typed:
test = driver.find_element(By.XPATH("//html//body//main//div//section//div//div//div//div[#class='tgme_widget_message_text js-message_text before_footer'][last()]"))
and in the error message you it is:
text=driver.find_element(By.XPATH("//html//body//main//div//section//div//div//div//div[#class='tgme_widget_message_text js-message_text before_footer'][last()]"))
And a quick awsner for your problem is that you try to call a string as a function
You are using the Selenium-Python clients, where as this line of code:
driver.find_element(By.XPATH("//html//body//main//div//section//div//div//div//div[#class='tgme_widget_message_text js-message_text before_footer'][last()]"))
is of Selenium-Java clients. Hence the TypeError.
Solution
Your effective line of code will be:
test = driver.find_element(By.XPATH, "//html//body//main//div//section//div//div//div//div[#class='tgme_widget_message_text js-message_text before_footer'][last()]")
source_code = test.text
print(source_code)
In a sigle line:
print(driver.find_element(By.XPATH, "//html//body//main//div//section//div//div//div//div[#class='tgme_widget_message_text js-message_text before_footer'][last()]").text)

Python Selenium. Element is not interactable

I am trying to fill the form on (https://all-access.wax.io). When I am using Javascript
document.getElementsByName("userName")[0].value = "Hello", then I am able to write text to a form. However, when I am using same concept in selenuim
driver.find_element_by_name("userName").send_keys("Hello"), then I am getting:
selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
When I am executing:
self.driver.find_element_by_name("userName")[1].send_keys("Hello") this leads to:
TypeError: 'WebElement' object is not subscriptable
I have also tried to wait until content is loaded, as well as use XPath and other selectors. I guess I am doing a simple mistake, but I can`t resolve it for several hours already.
Code to reproduce a problem:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
browser = webdriver.Chrome()
browser.get('https://all-access.wax.io')
browser.find_element_by_name("userName")[1].send_keys("hello")
print()
browser.find_element_by_xpath("(//input[#name='userName'])[2]").send_keys("hello")
You want to send_keys to the second input tag and not the first.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
browser = webdriver.Chrome()
browser.get('https://all-access.wax.io')
browser.find_element_by_name("userName").send_keys("hello")
print()
you are using find_element which returns a webelement and not array , use find_elements or remove the index
The approach with only name attribute did not work for me because when you are trying to access with [1] there are still two elements, so the locator is not unique.
So, I used the parent pannels visible-desktop-only-flex class and also added explicit wait.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
browser = webdriver.Chrome(executable_path='/snap/bin/chromium.chromedriver')
browser.get('https://all-access.wax.io')
wait = WebDriverWait(browser, 15)
wait.until(EC.element_to_be_clickable((By.XPATH, "//div[#class='pannels visible-desktop-only-flex']//input[#name='userName']")))
browser.find_element_by_xpath("//div[#class='pannels visible-desktop-only-flex']//input[#name='userName']").send_keys("hello")

Python Selenium fails to select search bar

I am trying to use selenium to search for courses on https://catalog.swarthmore.edu/ and scrape the results. All the selectors I have attempted to use fail, and when I print them out they return empty arrays. Why did these selectors fail, and what is the correct one? I get the "#keyword" and "span input" from hovering over and clicking on the search field with the chrome SelectorGadget extension, and I obtained the "span.show.clearfix input" and ".show.clearfix input" from examining the HTML with Chrome Devtools.
#import scrapy
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
import json
browserOptions = Options()
browserOptions.add_argument('--headless')
driver = webdriver.Chrome('C:/WebDriver/bin/chromedriver.exe', options=browserOptions)
def css(selector):
return driver.find_elements_by_id(selector)
driver.get("https://catalog.swarthmore.edu/")
print(driver.title)
search = css("span.show.clearfix input")#css("#keyword")#get search field
print(search)
print(css("span input"))
print(css(".show.clearfix input"))
print(css("#keyword"))
search.send_keys("ANCH 028")#enter your search.
search.submit()
search.clear()#clear search field
driver.quit()
Error message:
Traceback (most recent call last):
File "getDescWJSON.py", line 31, in
search.send_keys("ANCH 028")#enter your search.
AttributeError: 'list' object has no attribute 'send_keys'
The page has multiple elements with id=keyword so the results is a list. To send the keys, select the first element from the list:
Try this code:
search = css('keyword')[0] #("span.show.clearfix input")#css("#keyword")#get search field
You should probably change the name of the function css since it actually searches by element id.
You could simply do this to send the keys to that element. Wait for the element to come up after page load and send keys to the element.
search=WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//input[#id='keyword']"))).send_keys("ANCH 028")
Import
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
This worked for me:-
driver.get('https://catalog.swarthmore.edu/')
btn = driver.find_element_by_xpath('''/html/body/table/tbody/tr[3]/td[1]/table/tbody/tr[2]/td[2]/table/tbody/tr[1]/td/form/fieldset/span[3]/input[1]''')
btn.click() #you have to click it first
btn.send_keys("ANCH 028")

Python Selenium Upload a file via Windows Upload

I read a lot about and everyone advice to don't use the Windows Upload and write directly the path of my file; I even try to use some command found in the forum like:
swicthTo()
switch_to_window()
window_handles
but I didn't find any solution yet.
My main problem is that time I have no space to send directly the path of my file (see image below, the space to introduce the path is grey-out) but I have only the option to click in "Browse" and open the Windows Uploader:
Do you know how can I switch to the upload window's Windows and introduce my fie?
I try even in this way:
browse=wait(".//*[#id='fileinput']") #open the window upload
browse.click()
time.sleep(1)
def handle_dialog(element_initiating_dialog, dialog_text_input):
upload_dialog = driver.switch_to_active_element
print (upload_dialog)
upload_dialog.send_keys(dialog_text_input)
upload_dialog.send_keys(selenium.webdriver.common.keys.Keys.ENTER) # the ENTER key closes the upload dialog, other thread exits
handle_dialog(browse, "foobar.txt")
I find the windows and when I print I have this object:
We are already in the Location->Details Page <bound method WebDriver.switch_to_active_element of <selenium.webdriver.ie.webdriver.WebDriver (session="3e725bb7-40a7-452a-ad90-9cca1d41296a")>>
But after when I try to do send_keys I receive this error:
Traceback (most recent call last): File
"C:\Users\carlo.agresta\Desktop\IE - iQsonar.py", line 149, in
handle_dialog(browse, "foobar.txt") File "C:\Users\carlo.agresta\Desktop\IE - iQsonar.py", line 145, in
handle_dialog
upload_dialog.send_keys(dialog_text_input) AttributeError: 'function' object has no attribute 'send_keys'
I partially found a solution, I let behave my code as if the window upload is an alert so I do in this way:
browse=wait(".//*[#id='fileinput']")
browse.click()
time.sleep(1)
upload_dialog = driver.switch_to_alert()
print (upload_dialog)
upload_dialog.send_keys("C:\\Users\\carlo.agresta\\Desktop\\V4LabCredentials.csv")
Now my problem is that I can't accept accept and close the window :S any advice?
Thanks so much in advance
use autoit
example code:
import autoit
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
ActionChains(driver).move_to_element( driver.find_element_by_xpath("//div[#class='upload_button']")).click().perform()
handle = "[CLASS:#32770; TITLE:Open]"
autoit.win_wait(handle, 60)
autoit.control_set_text(handle, "Edit1", "\\file\\path")
autoit.control_click(handle, "Button1")

What is correct way to set send keys when use selenium and python

I'm new python (programming). Currently working on a project to fill up forms using selenium and python.
So for everything seems okay. I successfully installed python 3.6, selenium on pycharm and chrome drive on my windows.
I try to open a website and fill the form using the script. The script opens the site but couldn't put the texts in the form.
I have been browsing stack overflow and googling for hours and anything doesn't work.
It shows error regarding sendkeys.
Here's the full code
from selenium import webdriver
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
import time
# Replace below path with the absolute path
# to chromedriver in your computer
driver = webdriver.Chrome('C:\\Users\public\chromedriver.exe')
# Go to your page url
driver.get('https://www.website.com/')
# Get button you are going to click by its id ( also you could us find_element_by_css_selector to get element by css selector)
button_element = driver.find_element_by_class_name('signup_email_link')
button_element.click()
input_element = driver.find_element_by_name("first_name")
input_element.sendkeys(ram)
Here's the error code,
C:\Users\user\AppData\Local\Programs\Python\Python36-32\python.exe "C:/Users/user/PycharmProjects/My Projects/My scripts automate.py"
Traceback (most recent call last):
File "C:/Users/user/PycharmProjects/My Projects/My scripts automate.py", line 22, in <module>
input_element.sendkeys(ram)
AttributeError: 'WebElement' object has no attribute 'sendkeys'
Process finished with exit code 1
I even tried to replace the input_element with web_element but error continuous.
I use latest Python 3.6 version on pycharm.
Use
input_element.send_keys(ram)
instead of
input_element.sendkeys(ram)
It should be input_element.send_keys(ram).
List of methods here.

Categories

Resources