Get the first element in web with individual Xpath [duplicate] - python

This question already has answers here:
How to retrieve the title attribute through Selenium using Python?
(3 answers)
Closed 3 years ago.
I am running a little Python Selenium script and I want to access attributes from the first element on this site: https://www.mydealz.de/gruppe/spielzeug. Every few minutes the first element is different and has therefore a different Xpath identifier.
What are the possibilites to access all the time this first element, which has different id's/Xpaths? The first result I meant.
Thanks a lot in advance!

I've keep an eye open on the website for the last 15 minutes, but for me the page has not changed.
Nevertheless, I tried to scrape the data with BS4 (which you could populate with Selenium's current browser session), where it should always return the first element first.
from bs4 import BeautifulSoup
import requests
data = requests.get('https://www.mydealz.de/gruppe/spielzeug')
soup = BeautifulSoup(data.text, "html.parser")
price_info = soup.select(".cept-tp")
for element in price_info:
for child in element:
print(child)
Of course this is just for the price, but you can apply the same logic for the other elements.

To print the first title you have to induce WebDriverWait for the desired visibility_of_element_located() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "div.threadGrid div.threadGrid-title.js-contextual-message-placeholder>strong.thread-title>a"))).get_attribute("title"))
Using XPATH:
print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[#class='threadGrid']//div[#class='threadGrid-title js-contextual-message-placeholder']/strong[#class='thread-title']/a"))).text)
Note : You have to add 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
Console Output of two back to back execution:
[Mediamarkt #Ebay.de] diverse Gravitrax Erweiterungen günstig!
[Mediamarkt #Ebay.de] diverse Gravitrax Erweiterungen günstig!
As per the documentation:
get_attribute(name)
method Gets the given attribute or property of the element.
text
attribute returns The text of the element.

Related

Get element value from dynamic website using Selenium and Python [duplicate]

This question already has answers here:
How can I get text of an element in Selenium WebDriver, without including child element text?
(5 answers)
How to get text with Selenium WebDriver in Python
(9 answers)
How to get text element in html head by selenium?
(2 answers)
Closed 6 months ago.
I'm trying to get the value of the vending price of AMZN index market directly from the trading platform plus500, the value changes continuosly so I have to use selenium. The code I'm using is this one:
driver.get("https://app.plus500.com/trade/amazon")
# get AMZN vending price
Sell = driver.find_elements(By.CLASS_NAME, value="sell")
print(Sell)
The html from the source is this:
<div class="sell" data-no-trading="false" id="_win_plus500_bind873" data-show="true">126.28</div>
I need to scrape the value (in this case 126,28) every time it changes.
If it is needed I created a dummy Plus500 account for you: username "myrandomcode#gmail.com" password: "MyRandomCode87".
To extract the value of the vending price of AMZN index market directly from the trading platform plus500 i.e. the text 126.28 as the element is a dynamic element you need to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following locator strategies:
Using XPATH:
print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[starts-with(#class, 'section-table-body')]//span[text()='Amazon']//following::div[2]"))).text)
Note : You have to add 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 can find a relevant discussion in How to retrieve the text of a WebElement using Selenium - Python

Copied xpath directly from chrome, and not working

Trying to scrape odds from fanduel, goal is to get the player's name. In this case Jayson Tatum.
https://sportsbook.fanduel.com/basketball/nba/philadelphia-76ers-#-boston-celtics-31137202?tab=player-points
Even when I copy the xpath directly from chrome it doesnt seem to work. Though it works when I hardcode and look for an element through xpath containing the text Jayson Tatum.
This is my code
name = WebDriverWait(driver, 20).until(
EC.presence_of_element_located((By.XPATH,'//*[#id="root"]/div/div[2]/div[1]/div/div[2]/div[3]/div/div[2]/div/div[3]/div[1]/div/div/div[1]/span')))
Also tried this
name = driver.find_element(By.XPATH, '//*[#id="root"]/div/div[2]/div[1]/div/div[2]/div[3]/div/div[2]/div/div[3]/div[1]/div/div/div[1]/span')
Still get a NoSuchElement trying both ways.
To print the text Jayson Tatum you can use the following Locator Strategy:
Using xpath and text attribute:
print(driver.find_element(By.XPATH, "//span[text()='UNDER']//following::div[1]//span").text)
Ideally you need to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following Locator Strategy:
Using XPATH and get_attribute("innerHTML"):
print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//span[text()='UNDER']//following::div[1]//span"))).get_attribute("innerHTML"))
Note : You have to add 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 can find a relevant discussion in How to retrieve the text of a WebElement using Selenium - Python
References
Link to useful documentation:
get_attribute() method Gets the given attribute or property of the element.
text attribute returns The text of the element.
Difference between text and innerHTML using Selenium

I am trying to reference an element on Target's website, but am having issues grabbing it

I am trying to scrape some Target product information and am running into an issue trying to reference the UPC digits.
I am using Selenium on Python and am trying to reference the UPC and the digits, but there doesn't seem to be a way to reference the digits portion of it. I am currently trying:
UPC = driver.find_element_by_xpath("//*[text()[contains(.,'UPC')]]")
But this only returns the string 'UPC' and not the digits.
Does anyone know how to reference the entire element? I posted some images along with this, thank you!
To scrape the target product information element you need to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following Locator Strategies:
Using XPATH:
UPC = WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//*[contains(., 'UPC')]")))
Note : You have to add 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

List not printing all .text values using Selenium and Python

So I've been using selenium recently and decided to pull some values into a list using the following:
Values = browser.find_elements_by_xpath("//div[#class='main-col']//li[#class='test-item test-item--favourites']")
The values are all stored as expected. Though when I use for example:
for i in range (len(Values)):
print(Values[i].text)
i+=1
The code runs up to about the 50th index in the list and outputs the details, but after this its blank. I can run:
print(values[50])
It will output but .text gives me nothing.
Im using pYcharm for the development and looked into the variables at this stage. I can see that once I click on the variable it states 'collecting variable data' and after this I can then output some more of the variables in the list.
Is there a way I can force selenium to collect all the variable data so I can loop through each index in the list and store it in the .text format or is there a better alternative/method I can use?
If the .text is blank that means that there is no text between CSS Selector. To get an attribute out of a CSS Selector you have to use the get_attribute() function. Inside the () you place a string which is the name of an attribute which value you are looking for. for example
print(i.get_attribute('class'))
You are able to extract the text till the 50th index as find_elements_by_xpath() was able to identify 50 odd elements as per your Locator Strategy.
Solution
To collect all the desired elements using Selenium and python you have to induce WebDriverWait for visibility_of_all_elements_located() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR and get_attribute("innerHTML"):
print([my_elem.get_attribute("innerHTML") for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, "div.main-col li.test-item.test-item--favourites")))])
Using XPATH and text attribute:
print([my_elem.text for my_elem in WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//div[#class='main-col']//li[#class='test-item test-item--favourites']")))])
Note : You have to add 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

How to find element based on what its value ends with in Selenium?

I am dealing with a situation where every time I login a report is displayed in a table whose ID is dynamically generated with random text ending with "table".
I am automating this table with selenium python web driver. It has Syntax
driver.find_element_by_xpath('//*[#id="isc_43table"]/tbody/tr[1]/td[11]').click();
help me editing this syntax to match it with table ending id with "table".
(only one table is generated).
The ends-with XPath Constraint Function is part of XPath v2.0 but as per the current implementation Selenium supports XPath v1.0.
As per the HTML you have shared to identify the element you can use either of the Locator Strategies:
XPath using contains():
driver.find_element_by_xpath("//*[contains(#id,'table')]/tbody/tr[1]/td[11]").click();
Further, as you have mentioned that table whose ID is dynamically generated so to invoke click() on the desired element you need to induce WebDriverWait for the element to be clickable and you can use the following solution:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[contains(#id,'table')]/tbody/tr[1]/td[11]"))).click()
Alternatively, you can also use CssSelector as:
driver.find_element_by_css_selector("[id$='table']>tbody>tr>td:nth-of-type(11)").click();
Again, you can also use CssSelector inducing WebDriverWait as:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "[id$='table']>tbody>tr>td:nth-of-type(11)"))).click()
Note : You have to add 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
I hope, either these 2 will work for you
driver.find_element_by_xpath("//table[ends-with(#id,'table')]/tbody/tr[1]/td[11]").click();
OR
driver.find_element_by_xpath("//table[substring(#id,'table')]/tbody/tr[1]/td[11]").click();
If not getting, remove the tags from tbody.
For such situations, when you face randomly generated ids, you can use the below functions with XPATH expression
1) Contains,
2) Starts-with &
3) Ends-with
4) substring
Syntax
//table[ends-with(#id,'table')]
//h4/a[contains(text(),'SAP M')]
//div[substring(#id,'table')]
You need to identify the element which is having that id, whether its div or input or table. I think its a table.
You can try below XPath to simulate ends-with() syntax:
'//table[substring(#id, string-length(#id) - string-length("table") +1) = "table"]//tr[1]/td[11]'
You can also use CSS selector:
'table[id$="table"] tr>td:nth-of-type(11)'

Categories