Переходите к каждой ссылке с указанием c текста в HTML таблице - PullRequest
0 голосов
/ 08 мая 2020

На веб-странице есть таблица HTML. Я пытаюсь go по каждой имеющейся ссылке найти определенные слова внутри элементов href. Допустим, мне нужно найти «машину», «дом», «город». Если какое-либо из этих слов присутствует в тексте ссылок, я хочу, чтобы селен переходил к каждой ссылке, которая будет соответствовать критериям, и выполнять некоторые другие действия на подстраницах (у меня есть остальной код для операций с подстраницами).

HTML Table XPath: //*[@id="datatable"]

Мне, вероятно, нужно использовать что-то вроде?

            List<string> matchingLinks = new List<string>();

            ReadOnlyCollection<IWebElement> links = driver.FindElements(By.TagName("a"));

            // LINQ is better?
            foreach (IWebElement link in links)
            {
                string text = link.Text;
                if (Regex.IsMatch("car", text))
                {
                    matchingLinks.Add(text);
                }
            }

            foreach (string linkText in matchingLinks)
            {
                IWebElement element = driver.FindElement(By.LinkText(linkText));
                element.Click();

                driver.Navigate().Back();
            }

Однако это не принимает во внимание мою таблицу. Также, как назначить еще «поисковые слова» в дополнение к «машине»?

Links XPath (как вы можете видеть, только tr [7] изменяется в соответствии со строкой):

//*[@id="datatable"]/tbody/tr[1]/td[3]/a
...
//*[@id="datatable"]/tbody/tr[7]/td[3]/a
...
//*[@id="datatable"]/tbody/tr[11]/td[3]/a
//*[@id="datatable"]/tbody/tr[12]/td[3]/a

РЕДАКТИРОВАТЬ:

Пример:

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

namespace Tenders_Collection_Robot
{
    public static class WebDriverExtensions
    {
        public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds)
        {
            if (timeoutInSeconds > 0)
            {
                var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
                return wait.Until(drv => drv.FindElement(by));
            }
            return driver.FindElement(by);
        }
    }

    class Program
    {

        static void Main(string[] args)
        {

            // declare chrome options with prefs
            var options = new ChromeOptions();
            // options.AddArguments("headless"); // we add headless here

            options.AddUserProfilePreference("download.default_directory", "C:\\temp\\downloadfolder");
            options.AddUserProfilePreference("plugins.always_open_pdf_externally", true);

            var r = new Random();

            // Initialize the Chrome Driver // chromeOptions
            using (var driver = new ChromeDriver(options))
            {

                // Go to the home page
                driver.Navigate().GoToUrl("https://html.com/tables/");
                driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(15);

                ClickTableLink("col");
            }

        }

        public static void ClickTableLink(String value)
        {
            var driver = new ChromeDriver();

            var table = driver.FindElement(By.ClassName("related-elements"));
            foreach (var tr in table.FindElements(By.TagName("tr")))
            {
                var tds = tr.FindElements(By.TagName("a"));
                for (var i = 0; i < tds.Count; i++)
                {
                    if (tds[i].Text.Trim().Contains(value))
                    {
                        tds[i].Click();
                        break;
                    }

                }
            }
        }

    }
}

1 Ответ

1 голос
/ 08 мая 2020

Подбрасывая вам несколько идей, Хатман.

В отношении вашей первой функции ....

Вы можете передать значение для «name», а затем ...

using System.Linq;
using System.Collections.Generic;

        List<String> item = new List<string>();
        IReadOnlyList<IWebElement> cells = driver.FindElements(By.TagName("a"));
        foreach (IWebElement cell in cells)
        {
            item.Add(cell.Text);

        }

Затем запустите assert, любое из найденных значений "a" содержит текст?

        Assert.IsTrue(item.Any(itm => itm.Contains(name)));

Также вот что еще вы могли бы попробовать? Ниже «значение» может быть любым уникальным значением, которое вы ищете, например, адрес электронной почты, имя, номер учетной записи. «Значение» = i. Итак, если ваша ссылка находится в двух столбцах справа от i, вы можете сказать, что щелкните tds [i + 2] .Click () ;. Если ссылка, по которой вы хотите щелкнуть, находится в трех столбцах слева от i, tds [i-3] .Click (); Вы также можете взять текст отсюда и соответственно утверждать.

     public void ClickTableLink(String value)
   {
  var table =  driver.FindElement(By.Id("table"));
   foreach (var tr in table.FindElements(By.TagName("tr")))
  {
   var tds = tr.FindElements(By.TagName("a"));
    for (var i = 0; i < tds.Count; i++)
    {
        if (tds[i].Text.Trim().Contains(value))
        {
            tds[i].Click(); 
           break;
        }

    }
  }
}

Вот еще один пример .....

            <table id="mytable"> 
            <tr> 
            <th>Name</th> <th> Link1</th> <th>Favorite Color</th>  <th>Link2</th>
            </tr> 
            <tr> 
            <td>Bob</td> 
            <td><a href="https://foxnews.com">Fox</a></td> 
            <td>Yellow</td> 
            <td><a href="https://cnn.com">CNN</a> </td> 
            </tr> 

            <tr> 
            <td>Jim</td> 
            <td><a href="https://foxnews.com">News1</a></td> 
            <td>Blue</td> 
            <td><a href="https://cnn.com">News2</a> </td> 
            </tr> 
            <tr> 
            </tr> 
            </table> 

Это будет искать «Боб», извлекать текст из ссылки и проверять его соответствие значению 2.

        var value = "Bob";
        var value2 = "Fox";

        var table = Browser.FindElement_byId("mytable");
        foreach (var tr in table.FindElements(By.TagName("tr")))
        {
            var tds = tr.FindElements(By.TagName("td"));
            for (var i = 0; i < tds.Count; i++)
            {
                if (tds[i].Text.Trim().Contains(value))
                {
                    var test = tds[i + 1].Text.Trim();
                    Assert.IsTrue(test.Contains(value2));
                    break;
                }

            }
        }
...