I'm building an app with selenium for the first time, after watching a very basic tutorial on XPath. The app consists in a card's prize calculator. I wrote this code:
from selenium.webdriver import Chrome
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
cardmarket_url = "https://www.cardmarket.com/it/"
print("\nWhat are you searching for?\n\n")
index_product = 0
products = ["Yu-Gi-Oh", "Pokémon", "Magic", "Dragon Ball Super", "Flesh And Blood",
"Digimon", "Force of Will", "Final Fantasy", "World of Warcraft",
"Star Wars Destiny", "Weiss Schwarz", "Dragoborne", "My Little Pony",
"The Spoils"]
while (index_product <= 13):
print(f" [{str(index_product 1)}] - {prodotti[index_product]}")
index_product = index_product 1
gonext = False
while (gonext == False):
try:
product = products[int(input("\nInsert the product's number: "))-1]
gonext = True
except:
print("You can only insert numbers beetween 1 and 14.")
print(f"\nYou selected {product}.")
if product == "Yu-Gi-Oh":
product = "YuGiOh"
if product == "Pokémon":
product = "Pokemon"
if product == "Force of Will":
product = "FoW"
if product == "World of Warcraft":
product = "WoW"
if product == "Spoils":
product = "Spoils"
chrome_driver = ChromeDriverManager().install()
driver = Chrome(service=Service(chrome_driver))
driver.get(cardmarket_url product.replace(" ", ""))
searched = False
while (searched == False):
product = input("\nInsert card's name: ")
rarity = input("Insert card's rarity: ")
if product != "":
searched = True
else:
print("Insert product's name.")
product = product " " rarity
driver.find_element(By.ID, "ProductSearchInput").send_keys(product)
driver.find_element(By.ID, "search-btn").click()
driver.find_element(By.XPATH, '//div[@class, "col-12 col-md-8 px-2 flex-column"]/a[contains(text()="' product '")]').click()
input()
Well, the penultimate line gives me this error:
Traceback (most recent call last): File "C:\Users\Utente\OneDrive\Documenti\Progetti_Python\KivyApp\SeleniumCardFinder\CardFinder.py", line 59, in <module>
driver.find_element(By.XPATH, '//div[@class, "col-12 col-md-8 px-2 flex-column"]/a[contains(text()="' prodotto '")]').click() File "C:\Users\Utente\OneDrive\Documenti\Progetti_Python\KivyApp\kivy_venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 857, in find_element
return self.execute(Command.FIND_ELEMENT, { File "C:\Users\Utente\OneDrive\Documenti\Progetti_Python\KivyApp\kivy_venv\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 435, in execute
self.error_handler.check_response(response) File "C:\Users\Utente\OneDrive\Documenti\Progetti_Python\KivyApp\kivy_venv\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 247, in check_response
raise exception_class(message, screen, stacktrace) selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: Unable to locate an element with the xpath expression //div[@class, "col-12 col-md-8 px-2 flex-column"]/a[contains(text()="Mewtwo GX")] because of the following error: SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//div[@class, "col-12 col-md-8 px-2 flex-column"]/a[contains(text()="Mewtwo GX")]' is not a valid XPath expression. (Session info: chrome=103.0.5060.114) Stacktrace: Backtrace:
Ordinal0 [0x00796463 2188387]
Ordinal0 [0x0072E461 1762401]
Ordinal0 [0x00643D78 802168]
Ordinal0 [0x00646754 812884]
Ordinal0 [0x00646612 812562]
Ordinal0 [0x006468A0 813216]
Ordinal0 [0x00671595 988565]
Ordinal0 [0x00671B1B 989979]
Ordinal0 [0x0069E912 1173778]
Ordinal0 [0x0068C824 1099812]
Ordinal0 [0x0069CC22 1166370]
Ordinal0 [0x0068C5F6 1099254]
Ordinal0 [0x00666BE0 945120]
Ordinal0 [0x00667AD6 948950]
GetHandleVerifier [0x00A371F2 2712546]
GetHandleVerifier [0x00A2886D 2652765]
GetHandleVerifier [0x0082002A 520730]
GetHandleVerifier [0x0081EE06 516086]
Ordinal0 [0x0073468B 1787531]
Ordinal0 [0x00738E88 1805960]
Ordinal0 [0x00738F75 1806197]
Ordinal0 [0x00741DF1 1842673]
BaseThreadInitThunk [0x75436739 25]
RtlGetFullPathName_UEx [0x77068FEF 1215]
RtlGetFullPathName_UEx [0x77068FBD 1165]
CodePudding user response:
Change
//div[@class,"col-12 col-md-8 px-2 flex-column"]/a[contains(text()="Mewtwo GX")]
^ ^
to
//div[@]/a[contains(text(),"Mewtwo GX")]
^ ^
to eliminate your syntax problems, but be aware that
a[contains(text(),"Mewtwo GX")]
may not do what you're expecting. Consider instead
a[normalized-space()="Mewtwo GX"]
or
a/text()[contains(.,"Mewtwo GX")]
depending upon whether you wish to test that the anchor text equals some text or contains a substring of some text.
See also
- How to use XPath contains() for specific text?
- Testing text() nodes vs string values in XPath
- XPath 1.0 vs 2.0 different contains() behavior explanation
CodePudding user response:
i need to verify if it contains a substring of some text, then I've tried '//div[@]/a/text()[contains(.,"' prodotto '")]'
and '//div[@]a/text()[contains(.,"' prodotto '")]'
, but it gave me error.. a very long error, the last line of the error is
The result of the xpath expression "//div[@]/a/text()[contains(.,"Mewtwo GX ")]" is: [object Text]. It should be an element.