Scraping my search result on LinkedIn but having trouble locating certain buttons - python

I'm using python and Selenium to scrape some search results in LinkedIn but I'm having trouble finding the people button on the top left in order to filter my results to have only people. I noticed that the ID of the button is dynamic so I tried different ways to find the buttons, all of which have failed. Here is the HTML code of the button:
<div class="peek-carousel js-slideshow">
<ul class="peek-carousel__slides js-list">
<li class="mr2">
<button aria-checked="false" role="radio" aria-label="People" id="ember69" class="artdeco-pill artdeco-pill--slate artdeco-pill--2 artdeco-pill--choice ember-view search-reusables__filter-pill-button" type="button"> People </button>
and here are my three attempts (python code):
1) people_button = driver.find_element_by_css_selector("#people + button")
2) people_button = driver.find_element_by_xpath("//button[#aria-label='People']")
3) people_button = driver.find_element_by_xpath("//button[#aria-label='People'][#type='button']")
I'm having also the same problem for the next button on the bottom right to go to the next page here is the HTML code of the button:
<span class="artdeco-button__text">
Next
</span>

The first locator doesn't work because there is no element with an ID "people" on the page. The second and third work fine for me. I've tested them in the dev tools in Chrome using $$() for CSS selector and $x() for XPath. In this case, $x("//button[#aria-label='People']") returns a single element. My guess is that you need to add a wait.
I would use a CSS selector in this case because they are faster and better supported, e.g. "button[aria-label='People']". But, since you used XPath this should work
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
new WebDriverWait(driver, 10).until(EC.element_to_be_clickable(By.XPath("//button[#aria-label='People']"))).click()

Related

I can not access text box with selenium elements hid unless text clicked

I am working in python with Selenium. When I click on the line
<div tabindex="0" class="page click-enterkey" style="text-align: center; margin: 0px 1em; float: left;">7</div>
and copy the path with a click() or then send.keys(8) it will not go to page 8 it just flashes and keeps on moving to next line of code. But, as a human, if I click the box it changes the elements to show that second picture with an input section.
I have no clue what to do
magicBox = driver.find_element('xpath','//*[#id="searchResults"]/div[1]/div/div[1]/div[2]/div[2]').click()
magicBox.send_keys('7')
magicBox.send_keys(Keys.RETURN)
I also tried
magicBox = driver.find_element('xpath','//*[#id="searchResults"]/div[1]/div/div[1]/div[2]/div[2]').click().send_keys('7')
magicBox.send_keys(Keys.RETURN)
Image
It seems like you are encountering an issue with the send_keys() method not working as expected after you have clicked the element with the click() method.
Here's what you can try to resolve the issue:
First, make sure that you have imported the Keys module:
from selenium.webdriver.common.keys import Keys
After clicking the element, wait for the page to load before using send_keys(). You can use the WebDriverWait class and the expected_conditions module to wait for the element to be clickable before proceeding to the next step.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
magicBox = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="searchResults"]/div[1]/div/div[1]/div[2]/div[2]'))).click()
magicBox.send_keys('7')
magicBox.send_keys(Keys.RETURN)
This should resolve the issue and allow you to successfully send the keys to the element.
Given the HTML you provided, you are trying to send_keys() to a DIV which is not valid. My guess is that if you click the box that contains the "7" in your screenshot, an INPUT HTML element will appear in the DOM that you can send_keys() a new value to.
You might also check the URL and see if ?page=7 or something similar is there and you can just edit the URL to take you directly to the page you want.

Python and Selenium - Select specific radio button based on name and text within

I'm trying to use python and selenium to select a specific radio button out of a few that live within a web page. Luckily, the radio button that I want to select does have specific text associated, which should make it easier for me to select. Unfortunately, I'm missing something since all attempts have errored out. Below is the HTML code, what i've tried, and what i'm trying to achieve.
HTML
<div data-a-input-name="slotsRadioGroup" class="a-radio a-radio-fancy slotButtonRadio"><label><input type="radio" name="slotsRadioGroup" value="" autocomplete="off"><i class="a-icon a-icon-radio"></i><span class="a-label a-radio-label">
<span class="slotRadioLabel">
5PM - 7PM
</span>
<div class="a-row">
<span class="a-size-small slot-button-micro-copy preselected-visible">
Soonest available time with all items.
</span>
</div>
</span></label></div>
</div></div>
The radio button I need to select will always have the text "Soonest available..." present.
What I've tried
I've tried different variations of xpath code to attempt to select this based on the text. My last attempt was:
driver.find_element_by_xpath("//input[#type='radio']and following-sibling::span[contains(., 'Soonest available')").click()
Which results in the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//input[#type='radio']and following-sibling::span[contains(., 'Soonest available')' is not a valid XPath expression.
Expected Result
What I want is to be able to select the specific radio button based on the above text being present.
To Select Radio button based on text Induce WebDriverWait and wait for element_to_be_clickable() and following xpath options.
XPATH 1:
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//label[.//span[contains(.,'Soonest available time with all items')]]/input[#name='slotsRadioGroup']"))).click()
XPATH 2:
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//span[contains(.,'Soonest available time with all items')]/preceding-sibling::input[1]"))).click()
If Web driver click not work then you can try javascripts executor to click the same.
radiobtn=WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.XPATH,"//label[.//span[contains(.,'Soonest available time with all items')]]/input[#name='slotsRadioGroup']")))
driver.execute_script("arguments[0].click();", radiobtn)
Note:- You need to import following libraries.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Try this:
for i in driver.find_elements_by_tag_name("span"):
if "Soonest available" in i.text:
result = i
break

Clicking on a button with changing xpath

I just started working with Selenium webdriver to try automate clicking a button in a discord chat based on preconditions. The problem I am having is being able to classify this button.
For starters, the HTML code is as follows:
<div tabindex="0" class="reactionInner-15NvIl" aria-label="♥️, press to react" aria-pressed="false" role="button"><img src="/assets/1afd3c799f3e158662a70498e83e2a87.svg" alt="♥️" draggable="false" class="emoji"><div class="reactionCount-2mvXRV" style="min-width: 9px;">1</div></div>
What I first tried to do was to find_element_by_xpath:
driver.find_element_by_xpath('/html/body/div/div[1]/div/div[2]/div/div/div/div[2]/div[2]/div[2]/div[1]/div[1]/div/div/div[48]/div[1]/div[2]/div[2]/div[1]/div/div').click()
But, when a new opportunity for this reaction comes up, the xpath changes:
/html/body/div/div[1]/div/div[2]/div/div/div/div[2]/div[2]/div[2]/div[1]/div[1]/div/div/div[50]/div[1]/div[2]/div[2]/div[1]/div/div
Notice the only part changing it the div[48] to div[50]
The next thing I tried was to find_element_by_class_name:
element = driver.find_element_by_class_name('reactionInner-15NvIl')
driver.execute_script("arguments[0].click();", element)
The reason I did this was because I was having a problem with simply doing:
driver.find_element_by_class_name('reactionInner-15NvIl').click()
That code would give me an error saying Message: element click intercepted: Element <div tabindex="0" class="reactionInner-15NvIl" aria-label="💗, press to react" aria-pressed="false" role="button">...</div> is not clickable at point (405, 94). Other element would receive the click: <span id="NewMessagesBarJumpToNewMessages_122" class="span-3ncFWM">...</span> and the code wouldn't run. The program runs with the execute_script but it just isn't doing anything, the button is not being clicked. So if anyone has any idea how to be able to click this button, any help would be appreciated!
You can use xpath in a better way than navigate between the divs, like you did the first time.
First of all, if you can change the HTML to use id, or name, thats better.
In this case, you could use this xpath:
//div[#class = "reactionInner-15NvIl"]
When searching by class, this could return multiple results, so use the function find_elements_by_xpath, and then choose the exactly one
Induce WebDriverWait and wait for element_to_be_clickable() and following css selector.
WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"div[class*='reactionInner-'][role='button']"))).click()
You need to import following libraries.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
Update:
Induce Javascript Executor to click.
driver.execute_script("arguments[0].click();", WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"div[class*='reactionInner-'][role='button']"))))

Getting "element not visible" using selenium python for SAP EPM browser application

I am trying to automate an SAP EPM Application using Selenium Python. It's a browser based application. I am able to open the home page, after that I have to click on one tile. But I was unable to click it. It says "element not visible".
I tried using xpath, id but no luck.
Tile HTML:
<div class="tile tile-webdyn draggable tileBGColor ui-draggable ui-draggable-handle
ui-droppable border-norm" id="PLANCHGWO" style="position: relative;">
<div class="tileName">
<center>Change PM Order</center>
</div>
<div class="tileImage">
<center>
<img width="50px" height="50px" src="EDWO.png">
</center>
</div>
</div>
You could try invoking a wait, then click the desired WebElement with Javascript to work around the not visible error you are seeing.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
# wait for element to exist, then store it in tile variable
tile = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//center[text()='Change PM Order']")))
# click the element with Javascript
driver.execute_script("arguments[0].click();", tile)
If this does not work, we will probably need to see the full page HTML to understand the element you are trying to click. It's possible it is hidden in an iframe or obscured by other elements on the page.

Finding Element with Constantly Changing Xpath

I am new to coding Selenium in Python and, I have been trying to find this button through name, id, xpath, and then click on it but nothing has worked.
The issue is, I cannot find the button because the xpath is constantly changing, and the ID name is just "button", which locating it that way would not work either because there are a lot of other buttons on the page. How can I located the element?
Here is the sites HTML:
<ul data-componentname="gender">
<li id="b27296be-e8da-4d5a-acb6-d1674bf88568" class="">
<input type="button">
<span>Male</span>
</li>
<li id="32bf7074-6b69-41bb-9869-cf71ac42686f" class="">
<input type="button">
<span>Female</span>
</li>
Here is what I have tried:
clickGender = browser.find_element_by_xpath("b27296be-e8da-4d5a-acb6-d1674bf88568")
Any help is greatly appreciated.
As per the HTML you have shared to find the dynamic button corresponding to the text as Male or Female and then click on it you have to induce WebDriverWait for the element to be clickable and you can use the following solution:
Male:
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//ul[#data-componentname='gender']//li//span[contains(.,'Male')]//preceding::input[1]"))).click()
Female:
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//ul[#data-componentname='gender']//li//span[contains(.,'Female')]//preceding::input[1]"))).click()
Note: You need the following imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
You need to use find_element_by_id:
clickGender = browser.find_element_by_id("b27296be-e8da-4d5a-acb6-d1674bf88568")
Your XPATH should be this (assuming you want to select the 'Male' button):
//li[span/text()='Male']
To find the button with text that contains "Male", use this:
driver.find_element_by_xpath("//li[contains(string(), 'Male')]/input[contains(#type,'button')]")
To find the button with text that contains "Female", use this:
driver.find_element_by_xpath("//li[contains(string(), 'Female')]/input[contains(#type,'button')]")

Categories