Я пытаюсь сгенерировать CSS-селекторы для случайных элементов на веб-странице с помощью C #.Немного предыстории:
Я использую форму с элементом управления WebBrowser.Во время навигации можно запросить CSS-селектор элемента под курсором.Получение html-элемента тривиально, конечно, с помощью:
WebBrowser.Document.GetElementFromPoint(<Point>);
Задача состоит в том, чтобы создать «строгий» селектор CSS, ведущий к элементу под курсором, а-ля:
html > body > span:eq(2) > li:eq(5) > div > div:eq(3) > span > a
Этот селектор основан на: операторах eq, так как он предназначен для обработки jQuery и / или SizzleJS (эти две поддержки: eq - оригинальные селекторы CSS не делают. Спасибо @BoltClock за помощь в разъяснении этого).Итак, вы получите картину.Чтобы достичь этой цели, мы поставляем полученный HtmlElement для метода ниже и начинаем подниматься вверх по дереву DOM, запрашивая Parent для каждого элемента, с которым мы сталкиваемся:
private static List<String> GetStrictCssForHtmlElement(HtmlElement element)
{
List<String> familyTree;
for (familyTree = new List<String>(); element != null; element = element.Parent)
{
string ordinalString = CalculateOrdinalPositionAmongSameTagSimblings(element);
if (ordinalString == null) return null;
familyTree.Add(element.TagName.ToLower() + ordinalString);
}
familyTree.Reverse();
return familyTree;
}
private static string CalculateOrdinalPositionAmongSameTagSimblings(HtmlElement element, bool simplifyEq0 = true)
{
int count = 0;
int positionAmongSameTagSimblings = -1;
if (element.Parent != null)
{
foreach (HtmlElement child in element.Parent.Children)
{
if (element.TagName.ToLower() == child.TagName.ToLower())
{
count++;
if (element == child)
{
positionAmongSameTagSimblings = count - 1;
}
}
}
if (positionAmongSameTagSimblings == -1) return null; // Couldn't find child in parent's offsprings!?
}
return ((count > 1) ? (":eq(" + positionAmongSameTagSimblings + ")") : ((simplifyEq0) ? ("") : (":eq(0)")));
}
Этот метод надежно работал длямножество страниц.Однако есть одна конкретная страница, которая заставляет меня задуматься:
http://www.delicious.com/recent
Попытка получить селектор CSS любого элемента в списке (в центре страницы) не удалась для одногоочень простая причина:
После того, как вознесение достигает первого элемента SPAN на своем пути вверх (вы можете определить его, проверив страницу с помощью инструментов веб-разработчика IE9 для проверки), он пытается обработать его, вычислив его порядковое положениесреди его братьев и сестер.Для этого нам нужно попросить родительский узел для братьев и сестер.Здесь вещи становятся странными.Элемент SPAN сообщает, что его Parent является элементом DIV с id = "недавний индекс".Однако это не непосредственный родительский элемент SPAN (непосредственным родительским элементом является LI class = "wrap isAdv").Это приводит к сбою метода, потому что, что неудивительно, ему не удается обнаружить SPAN среди детей.
Но он становится еще более странным.Я извлек и изолировал HtmlElement самого SPAN.Затем я получил его Parent и использовал его, чтобы снова вернуться к элементу SPAN, используя:
HtmlElement regetSpanElement = spanElement.Parent.Children[0].Children[1].Children[1].Children[0].Children[2].Children[0];
Это вернуло нас к узлу SPAN, который мы начали ... однако с одним поворотом:
regetSpanElement.Parent.TagName;
Это теперь сообщает LI как родительский XX.Как это может быть?Есть идеи?
Еще раз спасибо заранее.
Примечания:
Я сохранил HTML-код (как он представлен в WebBrowser.Document.Html) и проверил сам, чтобы быть на 100% уверенным в том, что ничего смешного не происходит (то есть, для управления WebBrowser используется другой код, чем тот, который я вижу в IE9 - но этого не происходит, структура соответствует 100% для рассматриваемого пути).
Я управляю WebBrowser в IE9-режиме, используя инструкции, изложенные здесь:
http://www.west -wind.com / weblog / posts / 2011 / May / 21/ Web-Browser-Control-Specification-the-IE-Version
Попытка заставить элемент управления WebBrowser и IE9 работать так же, как это возможно.
Iподозреваю, что наблюдаемые эффекты могут быть вызваны тем, что за моей спиной работает какой-то скрипт.Однако мои познания в области веб-программирования не так велики, чтобы их закрепить.
Редактировать: Опечатки