我正在尝试遍历页面上的所有链接。转到每个页面并在链接页面上显示信息。在循环的第一次迭代中,程序正常工作。但在第二行
item.GetAttribute("href")
给出了错误。虽然 item 绝对是一个链接。在代码示例中,我删除了循环并重复相同的代码两次。但仍然出现错误
IWebDriver driver = new ChromeDriver();
driver.Url = @"https://forrest-med.ru/#services";
var elements = driver.FindElements(By.XPath("//a[contains(@href,'service/')]"));
await Task.Delay(1000);
var ar = elements.ToArray();
StringBuilder sb = new StringBuilder();
// for (int i = 0; i < ar.Length; i++)
// {
string href = "";
var item = ar[1]; //The link is the same
try
{
href = item.GetAttribute("href"); //First time.
//Everything is Ok
}
catch
{
// continue;
}
driver.Navigate().GoToUrl(href);
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
try
{
var el = driver.FindElement(By.ClassName("service-title"));
sb.Append(el.Text + "\n"); ;
}
catch
{
// continue;
}
driver.Navigate().Back();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
////////
href = "";
item = ar[1];//The link is the same
try
{
href = item.GetAttribute("href"); //Second time. Error
}
catch
{
// continue;
}
driver.Navigate().GoToUrl(href);
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
try
{
var el = driver.FindElement(By.ClassName("service-title"));
sb.Append(el.Text + "\n"); ;
}
catch
{
// continue;
}
driver.Navigate().Back();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
// }
parsingText.Text = sb.ToString();
如果您向我们提供有关您在第二个链接中看到的错误的详细信息,那就太好了。
但是,我几乎可以肯定,问题是您试图保留页面中不再存在的元素数组。每个元素只是浏览器中实际 DOM 元素的一个接口(有些可以方便地使用网关),因此一旦导航到第二个页面,前一个页面中的所有元素都会被销毁。您的数组上仍然有那些
IWebElement
实例,但它们指向任何地方。
据我所知,您只使用这些链接中的
href
,那么为什么不只存储您需要导航的那些 URL?
这是你的代码(如果我正确理解了一切),效果很好:
var driver = new ChromeDriver();
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
driver.Url = "https://forrest-med.ru/#services";
var elements = driver.FindElements(By.XPath("//a[contains(@href,'service/')]"));
var serviceUrls = elements.Select(e => e.GetAttribute("href")).ToList();
StringBuilder sb = new StringBuilder();
foreach (var url in serviceUrls)
{
driver.Navigate().GoToUrl(url);
if (driver.FindElement(By.ClassName("service-title")) is { } el)
{
string title = el.Text;
sb.AppendLine(title);
}
}
parsingText.Text = sb.ToString();