Using Python & Selenium to send message to friend in Facebook - python

I am currently writing a script in Python to log in on facebook and I want to send message to a friend. The script logs in to my facebook, and it manages to find my friend, but the message is not sent. I'm not 100% sure, but I think the problem is in the div tag/CSS on the text area (I commented out that piece of code).
Screenshot:
Text doesn't appear here
Here is my code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome('C:\path\chromedriver.exe')
driver.get('https://www.facebook.com/')
username_box = driver.find_element_by_id('email')
username_box.send_keys(USEREMAIL)
passElem = driver.find_element_by_id("pass")
passElem.send_keys(USERPASSWORD)
passElem.send_keys(Keys.RETURN)
userTargetUrl = "https://www.facebook.com/messages/t/" + "USERTAGET"
driver.get(userTargetUrl)
//The problem is here I think
elem = driver.find_element_by_css_selector("div textarea.uiTextareaNoResize")
while True:
elem.send_keys("Test")
elem.send_keys(Keys.RETURN)
driver.find_element_by_id("u_0_t").click()
The error code i get is:
selenium.common.exceptions.NoSuchElementException:
Message: no such element: Unable to locate element:
{"method":"css selector","selector":"div textarea.uiTextareaNoResize"}
(Session info: chrome=63.0.3239.132)
(Driver info: chromedriver=2.35.528161
(5b82f2d2aae0ca24b877009200ced9065a772e73),platform=Windows NT 10.0.15063 x86_64)

I solved this problem on RU SO)))
Briefly in steps:
Making the library import
from selenium.webdriver.common.action_chains import ActionChains
Visited the site
Logged in
You have a friend list, you clicked on your friend's icon and a chat window has opened.
now what to do?))
You need to place the cursor in the input line, in which the text is not written) Use for this .click (), you can use any of your XPath, but here is a shorter one))
driver.find_element_by_xpath("//*[#data-editor]").click()
After pressing the .click () method, the cursor is placed in the text input area. And now we need to enter the text, but use .send_keys() not with the pointer to the element, as you tried, but separately as an action (this is what the imported library is for)
actions = ActionChains(driver)
actions.send_keys('HI')
actions.perform()
Woo a la))))
Well, after that .click() on the send icon or press Enter)))))

Try to find the element by name, id, text or any other unique parameter - it would be better (they sometimes change the design and all xpaths and css-selectors become useless).
I made bold what I'd use:
<div aria-autocomplete="list" aria-controls="js_7" aria-describedby="js_0"
aria-expanded="false" <b>aria-label="Введите сообщение..."</b>
class="notranslate _5rpu" role="combobox" spellcheck="true"
style="outline: medium none currentcolor; -moz-user-select: text;
white-space: pre-wrap; overflow-wrap: break-word;" <b>tabindex="9999"<b>
<b>id="js_d"</b> contenteditable="true"><div data-contents="true">

Related

Python Selenium - Error: Element not Interactable. Interactive with website pop up window

I'm running a web scraper on my company's website so I can create elements every month. In testing, I have everything working until I get to interact with a pop up menu.
Code that interacts with pop up:
driver.get("www.website.com")
driver.find_element(By.ID, "ButtonCreatePeriod").click()
time.sleep(1)
driver.find_element(By.ID, "NoExpiration").click()
time.sleep(1)
driver.find_element_by_css_selector('[class="k-widget k-dropdown shorterDropDown"]').click()
time.sleep(3)
ddelement2 = driver.find_element_by_xpath("//*[text()='December 2021']")
action2 = ActionChains(driver)
action2.click(on_element=ddelement2).perform()
On action2.click(on_element=ddelement2).perform() I am getting the error:
"Message: element not interactable: [object HTMLLIElement] has no size and location"
I'm guessing this has to do with interacting with the popup.
Within the pop up that is opened with I click "ButtonCreatePeriod" I am opening the drop down menu defined as class="k-widget k-dropdown shorterDropDown".Within this drop down, I need to select the option with the text "December 2021". I cannot use IDs or numerical values here since this varies across other UIs in the website. The options shown on the dropdown are scrollable which could be an issue too.
I used this same code on another UI on the website with no issues but that one did not present a pop up, although it was scrollable.
Any ideas as to how I could have it select "December 2021" here?
Error generated per #cruisepandey suggestion:
Message: element click intercepted: Element <span title="" class="k widget
k-dropdown shorterDropDown k-state-disabled ic-dropdown-readonly"
unselectable="on" role="listbox" aria-haspopup="listbox" aria-
expanded="false" tabindex="0" aria-
owns="MfrCoreTermEffectivePeriodKey_listbox" aria-live="polite" aria-
disabled="false" aria-readonly="true" aria-busy="false" aria-
activedescendant="l581310d-64f8-4bbc-9354-71b6f041d0e3" style="">...
</span> is not clickable at point (434, 383). Other element would
receive the click: <p>...</p>
(Session info: chrome=93.0.4577.82)`
Solution
I basically had to dig deeper into the HTML code and use xpath to further define the lists within the drop down.
driver.find_element_by_css_selector('[class="k-widget k-dropdown shorterDropDown"]').click()
time.sleep(1)
driver.find_element_by_xpath("//div[#id='MfrCoreTermExpirationPeriodKey-list']//li[text()='December 2021']").click()
Possible reasons could be
Screen is not maximized, if so please maximize it when you launch the URL.
driver.maximize_window()
ActionChain may help.
time.sleep(5)
ActionChains(driver).move_to_element(driver.find_element(By.CSS_SELECTOR, ".k-widget.k-dropdown.shorterDropDown")).click().perform()
JS intervention with scrollInto view may help.
time.sleep(5)
ele = driver.find_element(By.CSS_SELECTOR, ".k-widget.k-dropdown.shorterDropDown")
driver.execute_script("arguments[0].scrollIntoView(true);", ele)
Imports :
from selenium.webdriver.common.action_chains import ActionChains

xpath not working properly with Selenium (python)

quick preface: I'm new to python and scraping so it's possible that I'm making an extremely obvious mistake.
I am trying to use Selenium to automate a few processes, the first of which is to open https://shop.anyseals.com/index.phtml and enter in a username and password.
This is how I am approaching it - A method that has worked for me without issue in the past with other websites.
from selenium import webdriver
import time
chromedriver = "A:\Downloads\chromedriver_win32 (1)/chromedriver"
driver = webdriver.Chrome(chromedriver)
driver.get("https://shop.anyseals.com/index.phtml")
#Let's wait for X seconds so that the elements can load.
time.sleep(3)
user = "username#user.com"
use = driver.find_element_by_xpath('//*[#id="userkey"]')
use.send_keys(user)
I'm using the xpath from the html associated with the username input. (html shown below)
<input name="userkey" id="userkey" style="width:100%" type="text"
onkeydown="if(event.keyCode=='13')perform_login('smp');">
I keep getting the error shown below that states that there is no such element.
What am I missing here?
selenium.common.exceptions.NoSuchElementException:
Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="userkey"]"}

Selenium driven browser shows different HTML code

I am not a very experienced coder so apologies if I say smth stupid.
I am using Python (in Spyder) to get Selenium to fill in a website form containing username and password. Here's the target - link.
When I lookup the "username" element by pressing F12 in a regular browser I get the following:
<input class="slds-input input" type="text" aria-describedby="" placeholder="Username" id="172:0" data-aura-rendered-by="176:0" data-interactive-lib-uid="2">
So I attempt to locate the element using the ID. However when I run the script, I get the following error in Chrome:
NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"[id="172:0"]"}
Same when I run it in Firefox instead:
NoSuchElementException: Unable to locate element: [id="172:0"]
When I check HTML in the Selenium driven browser, I can see that the page code is (ie element ID) different, as below
<input class="slds-input input" type="text" aria-describedby="" placeholder="Username" id="78:2;a" data-aura-rendered-by="82:2;a" data-interactive-lib-uid="2">
My best guess is that the difference in HTML code is the reason for error. I found people posting similar issues but those were slightly different and I was not able to solve my issue using the solutions proposed there. I would appreciate is someone could help with my case.
Use xpath instead of id since it changes dynamically
Xpath for UserName: //label/following-sibling::input
Xpath for Password: //lightning-input//div//input
Sample working code which works in java convert with using above xpath in python and also add implicitlyWait and pageLoadTimeout befor launching the website
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("https://lta-tennis.force.com/"); // WebElement
driver.findElement(By.xpath("//label/following-sibling::input")).sendKeys("dummy");
driver.findElement(By.xpath("//lightning-input//div//input")).sendKeys("dummy");
System.out.println(driver.getTitle());
Edit 1: Based on OP comment
This is working xpath
try these xpaths
//input[#placeholder="Username"]
//input[#placeholder="Password"]
here is the full code
from selenium import webdriver
import time
browser = webdriver.Chrome('C:\\driverpath\\chromedriver.exe')
url = 'https://lta-tennis.force.com/s/login/'
get = browser.get(url)
time.sleep(5)
browser.find_element_by_xpath('//input[#placeholder="Username"]').send_keys('hello')
browser.find_element_by_xpath('//input[#placeholder="Password"]').send_keys('pass')

Not able to click a button in Selenium (Booking.com)

I am programming a python scraper with help of Selenium. The first few steps are:
goes on booking.com, insert a city name, selects the first date and then tries to open the check-out calendar.
Here is where my problem occurs. I am not able to click the check-out calendar button (The important are of the website).
I tried to click every element regarding to the to check-out calendar (The elements of check-out calendar) with element.click(). I also tried the method
element = self.browser.find_element_by_xpath('(//div[contains(#class,"checkout-field")]//button[#aria-label="Open calendar"])[1]') self.browser.execute_script("arguments[0].click();", element)
It either does nothing (in case of execute.script() and click() on div elements) or it throws following exception when directly clicking the button:
Element <button class="sb-date-field__icon sb-date-field__icon-btn bk-svg-wrapper"
type="button"> is not clickable at point (367.5,316.29998779296875)
because another element <div class="sb-date-field__display"> obscures it
Here is a short code to test it:
browser = webdriver.Firefox()
browser.get("https://www.booking.com/")
wait = WebDriverWait(browser, 5)
element = wait.until(EC.presence_of_element_located((
By.XPATH, '(//div[contains(#class,"checkout-field")]//button[#aria-label="Open calendar"])[1]')))
element = wait.until(EC.element_to_be_clickable((
By.XPATH, '(//div[contains(#class,"checkout-field")]//button[#aria-label="Open calendar"])[1]')))
element.click()
I have a temporarily solution for my problem but I am not satisfied with it.
element = browser.find_element_by_xpath('(//div[contains(#class,"checkout-field")]//button[#aria-label="Open calendar"])[1]')
hov = ActionChains(browser).move_to_element(element)
hov.click().perform()
This will open the calendar by hovering over the object and clicking it. This strangely opens the calendar.
The methods mentioned above still don't work.
Define clicka as an xpath. Now use executescript to click the element.
driver.execute_script("arguments[0].click();", clicka)
I'm not 100% sure that I got everything you posted, because the layout is a bit messy.
However, I tried to test the issue with both Selenium Java and Firefox Scratchpad (a Web Developer tool that allows to run JavaScript scripts) and it worked perfectly - the button was clickable on both of them.
If you're interested in further testing using this tool, this is the code I've used:
In JavaScript:
function getElementByXpath(path) {
return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}
var myElement = getElementByXpath('(//div[contains(#class,"checkout-field")]//button[#aria-label="Open calendar"])[1]')
myElement.click()
and in Java:
FirefoxDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);
driver.navigate().to("https://www.booking.com");
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("(//div[contains(#class,'checkout-field')]//button[#aria-label='Open calendar'])[1]")));
driver.findElement(By.xpath("(//div[contains(#class,'checkout-field')]//button[#aria-label='Open calendar'])[1]")).click();
System.out.println("success");
if your are having the control check out button on all the web site managing with explicit wait required lots of codding you can use implicit wait below is in the java.
System.setProperty("webdriver.chrome.driver",
"G:\\TopsAssignment\\SampleJavaExample\\lib\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);

How to use find_element_by_link_text() properly to not raise NoSuchElementException?

I have a HTML code like this:
<div class="links nopreview"><span><a class="csiAction"
href="/WebAccess/home.html#URL=centric://REFLECTION/INSTANCE/_CS_Data/null">Home</a></span> • <span><span><a class="csiAction"
href="/WebAccess/home.html#URL=centric://SITEADMIN/_CS_Site">Setup</a></span> • </span><span><a
title="Sign Out" class="csiAction csiActionLink">Sign Out</a></span></div>
I would like to click on the link that has the text Home. As this Home link appears after login, I have a code like this:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import re
browser = webdriver.Firefox() # Get local session of firefox
browser.get("http://myServer/WebAccess/login.html") # Load App page
elem = browser.find_element_by_name("LoginID") # Find the Login box
elem.send_keys("Administrator")
elem = browser.find_element_by_name("Password") # Find the Password box
elem.send_keys("Administrator" + Keys.RETURN)
#try:
elem = browser.find_element_by_link_text("Home")
elem.click()
The part till login works great. However the last but one line is problematic
elem = browser.find_element_by_link_text("Home")
It raises this NoSuchElementException where the Home link is there as you can see from the HTML code.
raise exception_class(message, screen, stacktrace)
NoSuchElementException: Message: u'Unable to locate element: {"method":"link text","selector":"Home"}'
Any guidance as to what I am doing wrong, please?
Have you tried adding an implicit wait to this so that it waits instead of running to quickly.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import re
browser = webdriver.Firefox() # Get local session of firefox
browser.implicitly_wait(10) #wait 10 seconds when doing a find_element before carrying on
browser.get("http://myServer/WebAccess/login.html") # Load App page
elem = browser.find_element_by_name("LoginID") # Find the Login box
elem.send_keys("Administrator")
elem = browser.find_element_by_name("Password") # Find the Password box
elem.send_keys("Administrator" + Keys.RETURN)
#try:
elem = browser.find_element_by_link_text("Home")
elem.click()
The implicitly_wait call makes the browser poll until the item is on the page and visible to be interacted with.
The most common issues with NoSuchElementException while the element is there are:
the element is in different window/frame, so you've to switch to it first,
your page is not loaded or your method of page load is not reliable.
Solution could include:
check if you're using the right frame/window by: driver.window_handles,
write a wait wrapper to wait for an element to appear,
try XPath instead, like: driver.find_element_by_xpath(u'//a[text()="Foo"]').click(),
use pdb to diagnose your problem more efficiently.
See also: How to find_element_by_link_text while having: NoSuchElement Exception?
Maybe the element you are looking for doesn't exactly match that text string?
I know it can be tricky if it looks like it does on-screen, but sometimes there are oddities embedded like this simple markup "Home" or "Home" which makes the first char italic:
"<i>H</i>ome" is visually identical to "<em>H</em>ome" but does not match text.
Edit: after writing the above answer, I studied the question closer and discovered the HTML sample does show "Home" in plain text, but was not visible due to long lines not wrapping. So I edited the OP to wrap the line for readability.
New observation: I noticed that the Logout element has a "title" attribute, but the Home link element lacks such--try giving it one and using that.
Try adding an implicit wait to this in order to wait, instead of running too quickly.
Or
else you can import time and use time.sleep(25)

Categories

Resources