使用异步linq

时间:2018-11-04 14:21:52

标签: c# linq selenium-webdriver puppeteer puppeteer-sharp

我已经在Puppeter Sharp中重新编写了Selenium应用程序,以了解有关该框架的更多信息。我的应用程序在一个我无法访问其源代码的网站上运行,我只是在收集一些信息。

基于此,我使用Selenium编写了一个函数,该函数可以通过以下方式过滤IEnumerable<IWebElement>内的所需元素:

var element = Driver.FindElements(By.Id("User"))
    .First(x => 
           x.Text.ToLower().Trim() == "AAA" &&
           x.FindElement(By.Id("contact")).Text.ToLower().Trim() == "BBB")
    .FindElement(By.XPath("../input"));

但是我无法编写使用Puppeteer Sharp进行相同操作的代码。我写的最准确的方法是:

var users = await Page.QuerySelectorAllAsync("#User");
var baseElement = users.First(async x =>
    (await x.JsonValueAsync<string>()).ToLower().Trim() == "AAA" &&
    (await (await x.QuerySelectorAsync("#contact")).JsonValueAsync<string>()).ToLower().Trim() == "BBB");
var element = await baseElement.XPathAsync("../input");

上面的代码仍然向我返回错误:

  

无法将异步lambda表达式转换为委托类型'Func'。

是的,这很有意义,但是我无法使用linq找到另一种方法,使它至少清晰易读。

修改

HTML示例如下:我需要根据“攻击名称”和“类型”返回单选输入。我知道我可以编写一个很棒,丑陋且难以理解的xpath来为我查询它,但是我试图做一种更具可读性和流利性的方法,以便于维护。

<div id="player">
    <div class="attklist">
        <h2>Choose an Attack</h2>
        <ul>
            <li class="batsel" style="cursor: pointer;">
                <input type="radio" value="1" name="selected" checked="checked" id="atkopt1">
                <label for="atkopt1">Strength
                    <br><span class="tbtn tbtn-normal">normal</span>
                </label>
            </li>
            <li style="cursor: pointer;">
                <input type="radio" value="2" name="selected" id="atkopt2">
                <label for="atkopt2">Strength
                    <br><span class="tbtn tbtn-fighting">fighting</span>
                </label>
            </li>
            <li style="cursor: pointer;">
                <input type="radio" value="3" name="selected" id="atkopt3">
                <label for="atkopt3">Spectre Slash
                    <br><span class="tbtn tbtn-ghost">ghost</span>
                </label>
            </li>
            <li style="cursor: pointer;">
                <input type="radio" value="4" name="selected" id="atkopt4">
                <label for="atkopt4">Fire Puch
                    <br><span class="tbtn tbtn-fire">fire</span>
                </label>
            </li>
        </ul>
    </div>
</div>

1 个答案:

答案 0 :(得分:1)

从技术上讲,这是Linq方法上缺少的功能。编写异步Linq函数并不是那么简单。

另一方面,我发现用JavaScript直接实现这一点要简单得多。为什么?因为您可以在浏览器中测试脚本,然后将其移至C#代码。

例如,此方法将找到所有/^\d\d\d\d-(0?[1-9]|1[0-2])-(0?[1-9]|[12][0-9]|3[01]) (00|[0-9]|1[0-9]|2[0-3]):([0-9]|[0-5][0-9]):([0-9]|[0-5][0-9])*(:[0-9]*\+[0-9]*)?$/个元素,找到带有文本li的跨度的li,然后单击输入。

fire