Я пытаюсь создать селектор CSS для случайных элементов на веб-странице с помощью С#. Некоторые предпосылки:
Я использую форму с элементом управления WebBrowser. Во время навигации можно задать селектор CSS элемента под курсором. Получение html-элемента тривиально, конечно, с помощью:
WebBrowser.Document.GetElementFromPoint(<Point>);
Цель состоит в том, чтобы создать "строгий" css-селектор, ведущий к элементу под курсором, a-la:
html > body > span:eq(2) > li:eq(5) > div > div:eq(3) > span > a
Этот селектор основан на операторах eq, поскольку он предназначен для обработки jQuery и/или SizzleJS (эти две поддержки: eq - исходные селектор CSS не делают. Thumbs up @BoltClock, помогая мне прояснить это). Итак, вы получите картину. Чтобы достичь этой цели, мы предоставим восстановленный HtmlElement нижеуказанному методу и начнем подниматься вверх по дереву DOM, запросив родительский элемент каждого элемента, с которым мы сталкиваемся:
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 offsprings!?
}
return ((count > 1) ? (":eq(" + positionAmongSameTagSimblings + ")") : ((simplifyEq0) ? ("") : (":eq(0)")));
}
Этот метод работал надежно для разных страниц. Тем не менее, есть одна конкретная страница, которая делает мою голову в:
http://www.delicious.com/recent
Попытка извлечь CSS-селектор любого элемента в списке (в центре страницы) не удается по одной простой причине:
После того, как вознесение ударит по первому элементу SPAN в нем вверх (вы можете обнаружить его, проверив страницу с помощью инструментов веб-dev IE9 для проверки), он пытается обработать его, вычислив его порядковое положение среди тех же самых братьев-синглов. Для этого нам нужно спросить родителя node для братьев и сестер. Здесь все странно. Элемент SPAN сообщает, что Parent является элементом DIV с id = "recent-index". Однако не родительский немедленный для SPAN (непосредственным родителем является LI class= "wrap isAdv" ). Это приводит к сбою метода, потому что неудивительно, что он не обнаруживает SPAN среди детей.
Но он становится еще более странным. Я извлек и изолировал HtmlElement самого SPAN. Затем я получил его "Родитель" и использовал его, чтобы вернуться к элементу SPAN, используя:
HtmlElement regetSpanElement = spanElement.Parent.Children[0].Children[1].Children[1].Children[0].Children[2].Children[0];
Это привело нас к SPAN node, который мы начали... с одним поворотом:
regetSpanElement.Parent.TagName;
Теперь он сообщает LI как родительский X-X. Как это может быть? Любое понимание?
Еще раз заблаговременно.
Примечания:
-
Я сохранил код Html (как он был представлен в WebBrowser.Document.Html) и сам проверял его на 100% уверен, что ничего смешного не происходит (он же отличается от кода, который используется для управления WebBrowser, чем тот, который я вижу в IE9 - но это не происходит, если структура соответствует 100% для соответствующего пути).
-
Я запускаю элемент управления WebBrowser в IE9-режиме, используя инструкции, описанные здесь:
http://www.west-wind.com/weblog/posts/2011/May/21/Web-Browser-Control-Specifying-the-IE-Version
Попытка заставить управление WebBrowser и IE9 работать как можно ближе.
-
Я подозреваю, что наблюдаемые эффекты могут быть связаны с тем, что какой-то script работает за моей спиной. Однако мои знания пока не достигают с точки зрения веб-программирования, чтобы прикрепить его.
Изменить: Typos