我正在尝试从Youtube
的列表中单击歌曲。
在不共享所有课程的情况下,我会尽量简化工作,但仍会向您展示我正在使用的元素。
IwebDriver _webdriver = new ChromeDriver();
_webdriver.Navigate().GoToUrl("https://www.youtube.com/");
var element = wait.Until(x => x.FindElement(By.Id("search")));
element.SendKeys("Perfect");
var element = wait.Until(x => x.FindElement(By.CssSelector("#search-icon-legacy>yt-icon")));
element.Click();
var content = wait.Until(x => x.FindElement(By.Id("contents")));
var songHREF = content.FindElements(By.CssSelector("#video-title"));
songHREF[2].Click();
因此,发生的主要事情是90%的运行,songHREF
将单击实际上位于主页而非“结果”页面上的对象(歌曲的链接)。
其余的10%只会失败。找不到songHREF
元素(该元素不可见)。
答案 0 :(得分:0)
尝试等待元素可被点击:
var wait = new WebDriverWait(driver, TimeSpan.FromMinutes(1));
wait.Until(ExpectedConditions.ElementIsClickable(songHREF[2]));
songHREF[2].Click()
这将等待至少1分钟,直到可以单击元素,然后才能单击它。
完整代码如下:
IwebDriver _webdriver = new ChromeDriver();
_webdriver.Navigate().GoToUrl("https://www.youtube.com/");
var element = wait.Until(x => x.FindElement(By.Id("search")));
element.SendKeys("Perfect");
var element = wait.Until(x => x.FindElement(By.CssSelector("#search-icon-
legacy>yt-icon")));
element.Click();
// refresh the page
Driver.Instance.Navigate().Refresh();
var content = wait.Until(x => x.FindElement(By.Id("contents")));
var songHREF = content.FindElements(By.CssSelector("#video-title"));
var wait2 = new WebDriverWait(driver, TimeSpan.FromMinutes(1));
wait2.Until(ExpectedConditions.ElementIsClickable(songHREF[2]));
songHREF[2].Click();
我已经抓住了这个问题。有时,定位器在定位不可见元素时工作有误,但仅刷新页面将有助于修复它。注意:在像上面的代码片段中那样查找元素之前,请刷新页面。
搜索元素时的正常结果:
有时使用相同的定位符会得出此结果:
在这种情况下,前25个元素是不可见的。但是刷新页面后,结果类似于第一种情况(预期)。
答案 1 :(得分:0)
根据您的问题,一旦您发送了字符序列,例如 Perfect (完美)到 search 字段并启动搜索,您可以为所有歌曲创建一个 List ,然后根据您的选择进行选择。 在标题中包含文本歌词的歌曲,您可以在其上调用Click()
,并可以使用以下解决方案:
IwebDriver _webdriver = new ChromeDriver();
_webdriver.Navigate().GoToUrl("https://www.youtube.com/");
new WebDriverWait(_webdriver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementToBeClickable(By.CssSelector("input#search"))).SendKeys("Perfect");
_webdriver.FindElement(By.CssSelector("button.style-scope.ytd-searchbox>yt-icon")).Click();
IList<IWebElement> contents = new WebDriverWait(_webdriver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.VisibilityOfAllElementsLocatedBy(By.CssSelector("h3.title-and-badge.style-scope.ytd-video-renderer a")));
foreach (IWebElement content in contents)
if(content.GetAttribute("innerHTML").Contains("Lyrics"))
{
content.Click();
break;
}