且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Linq查询仅从表的第一行中选择值

更新时间:2023-02-05 17:09:42

您似乎希望 driver.FindElements(...)返回的每个元素都是< divclass ="ui-widget-content slick-row ..."> 元素.一个简单的CSS选择器应该可以解决问题:

It looks like you expect each element returned by driver.FindElements(...) to be a <div class="ui-widget-content slick-row ..."> element. A simple CSS selector should do the trick:

var rows = driver.FindElements(By.CssSelector("#users_table .slick-viewport .slick-row"));

LINQ语句如下:

var DataHere = from row in driver.FindElements(By.CssSelector("#users_table .slick-viewport .slick-row"))
               select new
               {
                   ...
               };

在每一行中,您需要找到单元格"似乎是< div class ="slick-cell"> .您的xpath都以//开头以查找每个单元格.这些xpath将在全局范围内进行评估-它将搜索 entire 网页.您想将xpath的作用域限定为每一行.代替:

Within each row you need to find "cells" which seem to be <div class="slick-cell">. Your xpaths all begin with // to find each cell. Those xpaths will be evaluated globally — it will search the entire web page. You want to scope the xpaths to each row. Instead of:

rows.FindElement(By.XPath("//div[contains(@class, 'slick-cell l0 r0')]"))

您要在每个xpath前面加上.字符:

You want to prefix each xpath with a . character:

      row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l0 r0')]"))
                                ^
                                |
This becomes relative xpath ----+

.字符表示Selenium将在当前 row 对象中搜索,这是您在本例中想要的.如果不这样做,Selenium将返回整个网页中与XPath表达式匹配的第一个元素.

The . character means Selenium will search within the current row object, which is what you want in this case. If you don't, Selenium returns the very first element in the entire web page that matches the XPath expression.

我还建议创建一个代表每个对象的正确的页面对象模型行:

I would also recommend creating a proper page object model representing each row:

public class UserTableRow
{
    private readonly IWebElement row;

    public string Username => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l0 r0')]")).Text,
    public string Firstname => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l1 r1')]")).Text,
    public string Lastname => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l2 r2')]")).Text,
    public string Type => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l3 r3')]")).Text,
    public string Crew => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l4 r4')]")).Text,
    public string JobTitle => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l5 r5')]")).Text,
    public string DefaultPrice => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l6 r6')]")).Text,
    public string Future => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l7 r7')]")).Text,
    public string Language => row.FindElement(By.XPath(".//div[contains(@class, 'slick-cell l8 r8')]")).Text,

    public UserTableRow(IWebElement row)
    {
        this.row = row;
    }
}

这将真正清理您的LINQ语句:

This will really clean up your LINQ statement:

var DataHere = from row in driver.FindElements(By.CssSelector("#users_table .slick-viewport .slick-row"))
               select new UserTableRow(row);