Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
104 views
in Technique[技术] by (71.8m points)

How to look for text via XPath using Selenium for C#?

Im trying to achieve checking for the text "In stock.", via a XPath query, however my XPath variable elementInStock returns a ID, and it looks like its not finding the text "In stock.", from the URL https://www.amazon.co.uk/dp/B08H96W864/ref=twister_B08J4RCVXW?_encoding=UTF8&th=1

Would appreciate some help how to find the text "In stock." and do the Console.WriteLine("HEYYYY");

if text "In stock." not found then keep go to the while loop in mu code, my logic does not even go to the while loop if XPATH is null.

Please advise.

class Program
    {
        static void Main(string[] args)
        {

            IWebDriver driver = new ChromeDriver();

            //Navigate to
            driver.Navigate().GoToUrl("https://www.amazon.co.uk/dp/B08H96W864/ref=twister_B08J4RCVXW?_encoding=UTF8&th=1");

            driver.Manage().Window.Maximize();


            IWebElement elementInStock = driver.FindElement(By.XPath("/html/body/div[2]/div[2]/div[5]/div[4]/div[4]/div[18]"));

            

            if (elementInStock != null)
            {
                Console.WriteLine("HEYYYY");
            }

            else if (elementInStock == null)
                {
                    int counter = 0;

                    while (counter < 10)
                    {

                        Thread.Sleep(2500);

                        driver.Navigate().Refresh();

                    }
                }


            }
        }
    }
question from:https://stackoverflow.com/questions/65930580/how-to-look-for-text-via-xpath-using-selenium-for-c

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I see a few things that might be causing the issues you are seeing and a few other things that will cause issues later. I'll list them here and then below I've made some suggestions for improving the script. Finally, I've updated the script with the suggested improvements. I've tested the code and it's working correctly.

  1. The fact that you don't wait for the element to be visible may be part of the problems you are seeing.
  2. Your script doesn't actually check for the "In stock." text.
  3. There's really no such thing as a null element result of a .FindElement() call. The find either works and returns the element or it doesn't work and it throws an exception. That's why your code never gets to the while loop when the element isn't found. My recommendation here would be to either find an element that you know will always be present or use .FindElements() (plural) and then check to see if there's an element in the returned collection (meaning the element exists). This will avoid unnecessary exceptions being thrown and will still accomplish the task.
  4. Thread.Sleep() takes milliseconds as the parameter so 2500 is 2.5s. I'm assuming you intended to wait for more than 2.5s? I prefer to use TimeSpan.FromSeconds(30) to make it clearer how many seconds I'm waiting. NOTE: There are also many other From* options you may be interested in using also, e.g. TimeSpan.FromMinutes(2).
  5. You never increment counter... meaning your script will be stuck in an infinite loop.
  6. Your XPath is an absolute XPath which means that it starts at the /html tag. This is considered a bad practice because you end up with a very strict (and typically long) XPath which if any element along the specified chain is added/deleted/changed, your XPath will break. If you have to use XPath, instead create a relative XPath with the minimal information needed to uniquely locate the element. Best practice would be to use an ID or CSS selector instead and only use an XPath for locating an element by contained text or for more complex scenarios.

I would suggest a few changes...

  1. In this case, we can use an ID, availability, on the parent element instead of using XPath.

     <div id="availability" class="a-section a-spacing-none">
         <span class="a-size-medium a-color-success">In stock.</span>
     </div>
    

    NOTE: I've cleaned up a LOT of extra whitespace from the HTML above to save space. It won't matter in this case given that I'm planning to use the ID to locate the element but I am going to add .Trim() to the text returned to remove all that extra whitespace.

  2. Add a wait to make sure the element is visible.

  3. Find an element that is always there and check the contained text for the desired string.

  4. Increment counter.

Here's what the final code looks like. I ran this code and it successfully wrote "HEYYYY" to the console.

using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;
using System;
using System.Threading;

class Program
{
    static void Main(string[] args)
    {
        IWebDriver driver = new ChromeDriver();
        driver.Manage().Window.Maximize();
        driver.Url = "https://www.amazon.co.uk/dp/B08H96W864/ref=twister_B08J4RCVXW?_encoding=UTF8&th=1";

        int counter = 0;
        while (counter < 10)
        {
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(15));
            IWebElement availability = wait.Until(ExpectedConditions.ElementIsVisible(By.Id("availability")));
            if (availability.Text.Trim() == "In stock.")
            {
                Console.WriteLine("HEYYYY");
                break;
            }

            counter++;
            Thread.Sleep(TimeSpan.FromSeconds(30));
            driver.Navigate().Refresh();
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...