如何从youtube的搜索结果中选择歌曲?

时间:2018-07-19 10:18:55

标签: c# selenium selenium-webdriver css-selectors webdriverwait

我正在尝试从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元素(该元素不可见)。

2 个答案:

答案 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();

我已经抓住了这个问题。有时,定位器在定位不可见元素时工作有误,但仅刷新页面将有助于修复它。注意:在像上面的代码片段中那样查找元素之前,请刷新页面。

搜索元素时的正常结果:

img

有时使用相同的定位符会得出此结果:

img2

在这种情况下,前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; 
    }